分布式锁-Redis方案
1 #!/usr/bin/env python 2 # coding=utf-8 3 4 import time 5 import redis 6 7 class RedisLock(object): 8 def __init__(self, key): 9 self.rdcon = redis.Redis(host='', port=6379, password="", db=1) 10 self._lock = 0 11 self.lock_key = "%s_dynamic_test" % key 12 13 @staticmethod 14 def get_lock(cls, timeout=10): 15 while cls._lock != 1: 16 timestamp = time.time() + timeout + 1 17 cls._lock = cls.rdcon.setnx(cls.lock_key, timestamp) 18 # 注意下方括号的范围 19 if cls._lock == 1 or (time.time() > cls.rdcon.get(cls.lock_key) and time.time() > cls.rdcon.getset(cls.lock_key, timestamp)): 20 print "get lock" 21 break 22 else: 23 time.sleep(0.3) 24 25 @staticmethod 26 def release(cls): 27 if time.time() < cls.rdcon.get(cls.lock_key): 28 print "release lock" 29 cls.rdcon.delete(cls.lock_key) 30 31 def deco(cls): 32 def _deco(func): 33 def __deco(*args, **kwargs): 34 print "before %s called [%s]."%(func.__name__, cls) 35 cls.get_lock(cls) 36 try: 37 return func(*args, **kwargs) 38 finally: 39 cls.release(cls) 40 return __deco 41 return _deco 42 43 @deco(RedisLock("112233")) 44 def myfunc(): 45 print "myfunc() called." 46 time.sleep(20) 47 48 49 if __name__ == "__main__": 50 myfunc()
eg2:
1 import redis 2 import time, datetime 3 4 5 def acquire_lock(conn, lockname, identifier, expire=10): 6 if conn.setnx(lockname, identifier): 7 conn.expire(lockname, expire) 8 return identifier 9 elif not conn.ttl(lockname): 10 conn.expire(lockname, expire) 11 12 return False 13 14 15 def release_lock(conn, lockname, identifier): 16 pipe = conn.pipeline(True) 17 while True: 18 try: 19 pipe.watch(lockname) 20 if pipe.get(lockname) == identifier: 21 pipe.multi() 22 pipe.delete(lockname) 23 pipe.execute() 24 return True 25 pipe.unwatch() 26 break 27 except redis.exceptions.WatchError: 28 pass 29 30 # we lost the lock 31 return False 32 33 34 conn = redis.Redis(host='localhost', port=6379, db=0) 35 36 # 1 identifier 37 # 2 False 38 # 11 True 39 # 22 False 40 # 33 barx2 41 # 44 True 42 43 ret = acquire_lock(conn, "lockname", "identifier", 3) 44 print "1", ret 45 ret = acquire_lock(conn, "lockname", "identifier", 3) 46 print "2", ret 47 ret = release_lock(conn, "lockname", "identifier") 48 print "11", ret 49 ret = release_lock(conn, "lockname", "identifier") 50 print "22", ret 51 52 ret = acquire_lock(conn, "footest", "bartest", 10) 53 print "33", ret