--python Based Distributed Lock the redis

Directly on the code

. 1  # Coding. 8 = UTF- 
2  
. 3  
. 4  # reasons for using a distributed lock redis implemented 
. 5  # . 1 redis good performance 
. 6  # 2 redis command better support for this, it was easier to achieve 
. 7  
. 8  "" " 
. 9  redis Commands
 10      val SETNX key if and only if the key does not exist, a sET key is a string of val, returns 1; if the key is present, then do nothing, returns 0
 . 11      the expire a key timeout set timeout time key, the unit is second , over this time the lock will be released automatically, to avoid deadlock
 12      the delete Key delete Key
 13  "" " 
14  Import time
 15  Import uuid
 16  from Threading Import the Thread
 17  
18 import redis
19 
20 redis_client = redis.Redis(host="localhost", port=6379, db=2)
21 
22 
23 def acquire_lock(lock_str, acquire_time=10, time_out=10):
24     """设置锁"""
25     lock_key = "string:lock:" + lock_str
26     identifier_uuid_str = str(uuid.uuid4())
27     end = time.time() + acquire_time
28 
29     try:
30         while time.time() < end:
31 is              IF redis_client.setnx (lock_key, identifier_uuid_str):
 32                  # Set the timeout process to prevent crashes other processes can not obtain a lock 
33 is                  redis_client.expire (lock_key, Time = time_out)
 34 is                  return identifier_uuid_str
 35  
36              elif  Not redis_client.ttl (lock_key) :
 37 [                  redis_client.expire (lock_key, Time = time_out)
 38 is              the time.sleep (0.01 )
 39      the finally :
 40          # release lock 
41 is          redis_client.delete (lock_key)
 42 is          return False
 43 is  
44 is 
45 def release_lock(lock_str, identifier_uuid_str):
46     """释放锁"""
47     lock = "string:lock:" + lock_str
48     pip = redis_client.pipeline(True)
49     while True:
50         try:
51             pip.watch(lock)
52             lock_value = redis_client.get(lock)
53             if not lock_value:
54                 return True
55 
56             if lock_value.decode() == identifier_uuid_str:
57                 pip.multi()
58                 pip.delete(lock)
59                 pip.execute()
60                 return True
61             pip.unwatch()
62             break
63         except redis.exceptions.WatchError:
64             pass
65     return False
66 
67 
68 # 秒杀demo
69 def seckill(product_id, t_id):
70     identifier_uuid_str = acquire_lock(product_id)
71     if not identifier_uuid_str:
72         return "error " 
73 is      Print  " Thread: {} - obtained lock " .format (t_id)
 74      Stock = int (redis_client.get ( " Stock " ))
 75      IF Stock> 0:
 76          real_stock Stock = -. 1
 77          redis_client.set ( " Stock " , STR (real_stock))
 78          Print  " thread: {} - grab a product, the remaining inventory element {} " .format (t_id, real_stock)
 79      the else :
 80          Print  " thread: {} - He did not grab, inventory shortage " .
format(t_id)
81         return
82     release_lock(product_id, identifier_uuid_str)
83     print "线程:{}--释放了锁".format(i)
84 
85 
86 # redis-cli: set stock 20
87 for i in range(25):
88     product_id = "product_001"
89     t = Thread(target=seckill, args=(product_id, i,))
90     t.start()

Actually there is a problem, if the execution time of the task exceeds the period of lock will cause other processes to acquire the lock, the lock is not a case of the release of the current task plus the lock will appear, where you can open another thread continuously within a certain time continued life for the lock.

Guess you like

Origin www.cnblogs.com/82nlf-xlqb/p/12116167.html