基于Python
import time
import uuid
from multiprocessing import Process
import redis
redis_client = redis.Redis(host='42.193.152.252', port='6379', db='0', password='Ww550076')
# 加锁
def acquire_lock(lock_name, args, acquite_timeout=30, time_out=120):
'''
lock_name 锁名字
args 为进程名字
acquite_timeout 客户端获取锁--循环执行时间
time_out 分布式锁过期时间
'''
identifier = str(uuid.uuid4())
end = time.time() + acquite_timeout
lock_names = 'lock_name:' + lock_name
print(f"进入加锁进程{str(args)} end_time:{end}")
while time.time() < end: # 客户端执行时间
if redis_client.setnx(lock_names, identifier): # 设置key的值设置为value
print('正在加锁:进程' + str(args))
print(f'正在加锁value: {identifier}')
redis_client.expire(lock_name, time_out) # 给key设置过期时间
return identifier
elif redis_client.ttl(lock_name) == -1: # 查询key的过期时间, 没设置生存时间返回-1, 不存在-2,
redis_client.expire(lock_name, time_out)
time.sleep(0.01)
return False # 客户端超时返回false
# 释放锁
def release_lock(lock_name, identifire):
lock_names = "lock_name:" + lock_name
pipe = redis_client.pipeline(True) # 事务
print('开始释放锁')
while True:
try:
pipe.watch(lock_names) # 监控key, key在事务过程中发生改变则失败
print('释放锁uuid:',pipe.get(lock_names))
if pipe.get(lock_names).decode() == identifire:
pipe.multi() # 队列
pipe.delete(lock_names)
pipe.execute() # 提交
return True
pipe.unwatch() # 关闭监控
print('释放锁完毕')
break
except redis.exceptions.WatchError:
pass # 释放锁时间, 有其他客户端改变了键值对,锁释放失败,进行循环
return False
# 测试
def exec_test(lock_name, args):
identifire = acquire_lock(lock_name, args) # 加锁
# print(f'加锁成功,identifire: {identifire}')
if identifire:
time.sleep(3)
res = release_lock(lock_name, identifire)
print(f'释放完成:{res}')
else:
print('获取redis分布式锁失败,其他进程正在使用')
if __name__ == '__main__':
for i in range(0, 5):
Process(target=exec_test, args=('test', i)).start()

