import redis import time S_REDIS = redis.Redis( host='10.127.0.0', port='8088', db=9, password='test', decode_responses=True, retry_on_timeout=True, health_check_interval=10, socket_timeout=120, socket_keepalive=True ) class ShareLock: def __init__(self, key, timeout=60): """ :param key: 共享锁的名称 :param timeout: 共享锁的超时时间 """ self.redis = S_REDIS self.lock_name = key self.timeout = timeout def acquire(self): # 这里时间值不能用datetime,应该是时间戳函数time.time() # now = begin = datetime.now() now = begin = time.time() while now - begin < self.timeout: # setnx并没有设定键的过期时间,所以可以使用两种方式进行处理,方式1:expire(key, ttl), 方式2:业务侧判断锁过期 flag = self.redis.setnx(self.lock_name, now + self.timeout + 1) # setnx返回值为1,代表获取到分布式锁 if flag == 1: return True # 接下来使用业务侧判断锁过期方式来实现分布式锁 lock_release_time = self.redis.get(self.lock_name) if not lock_release_time: time.sleep(1) continue # 在判断到锁过期的情况下,如果其他进程已经重新获取到锁,这个是考虑的情况1,情况2就是如果没有设置过期时间,获取锁的进程 # 没有release锁的情况,这个时候我们判断超时后需要重新set if now > int(lock_release_time): # 如果超时,当前进程刷新lock_name对应的时间,代表获取到锁, 其他进程等待 old_lock_time = self.redis.getset(self.lock_name, now + self.timeout + 1) # 如果锁释放了,getset的值为none,此时重新走setnx逻辑获取锁 if old_lock_time and int(old_lock_time) == int(lock_release_time): # 这里要考虑一种特殊情况,如果两个进程都走进去当前逻辑, 此时需要再进一步判断锁的时间, 判断确实是当前进程重置了锁过期时间 return True time.sleep(1) now = time.time() return False def release(self): """ :return: """ self.redis.delete(self.lock_name) def __enter__(self): self.acquire() def __exit__(self, exc_type, exc_val, exc_tb): self.release()
import redis标签:实现,lock,self,Redis,timeout,time,release,now,分布式 From: https://www.cnblogs.com/kevin-zsq/p/16844650.html
import time
S_REDIS = redis.Redis(
host='10.127.0.0',
port='8088',
db=9,
password='test',
decode_responses=True,
retry_on_timeout=True,
health_check_interval=10,
socket_timeout=120,
socket_keepalive=True
)
class ShareLock:
def __init__(self, key, timeout=60):
"""
:param key: 共享锁的名称
:param timeout: 共享锁的超时时间
"""
self.redis = S_REDIS
self.lock_name = key
self.timeout = timeout
def acquire(self):
# 这里时间值不能用datetime,应该是时间戳函数time.time()
# now = begin = datetime.now()
now = begin = time.time()
while now - begin < self.timeout:
# setnx并没有设定键的过期时间,所以可以使用两种方式进行处理,方式1:expire(key, ttl), 方式2:业务侧判断锁过期
flag = self.redis.setnx(self.lock_name, now + self.timeout + 1)
# setnx返回值为1,代表获取到分布式锁
if flag == 1:
return True
# 接下来使用业务侧判断锁过期方式来实现分布式锁
lock_release_time = self.redis.get(self.lock_name)
if not lock_release_time:
time.sleep(1)
continue
# 在判断到锁过期的情况下,如果其他进程已经重新获取到锁,这个是考虑的情况1,情况2就是如果没有设置过期时间,获取锁的进程
# 没有release锁的情况,这个时候我们判断超时后需要重新set
if now > int(lock_release_time):
# 如果超时,当前进程刷新lock_name对应的时间,代表获取到锁, 其他进程等待
old_lock_time = self.redis.getset(self.lock_name, now + self.timeout + 1)
# 如果锁释放了,getset的值为none,此时重新走setnx逻辑获取锁
if old_lock_time and int(old_lock_time) == int(lock_release_time):
# 这里要考虑一种特殊情况,如果两个进程都走进去当前逻辑, 此时需要再进一步判断锁的时间, 判断确实是当前进程重置了锁过期时间
return True
time.sleep(1)
now = time.time()
return False
def release(self):
"""
:return:
"""
self.redis.delete(self.lock_name)
def __enter__(self):
self.acquire()
def __exit__(self, exc_type, exc_val, exc_tb):
self.release()