Fork me on GitHub

分布式锁-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
复制代码

 

posted @   AnimalRabbit  阅读(246)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示