import time
import uuid
from multiprocessing import Process
import redis
# 连接到 Redis 服务器
redis_client = redis.Redis(host='localhost', port=6379, password='', db=0)
# 加锁的过程
def acquire_lock(lock_name, args, acquite_timeout=30, time_out=120):
"""
获取分布式锁
Args:
lock_name: 锁的名称
args: 获取锁的参数
acquite_timeout: 获取锁的超时时间
time_out: 锁的过期时间
Returns:
True: 获取锁成功
False: 获取锁失败
"""
# 生成一个唯一的标识符
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):
# 设置锁的过期时间
redis_client.expire(lock_name, time_out)
# 获取锁成功,返回 True
return identifier
# 锁已经被占用,等待一段时间,然后重试
time.sleep(0.001)
# 获取锁失败,返回 False
return False
# 锁的释放
def release_lock(lock_name, identifire):
"""
释放分布式锁
Args:
lock_name: 锁的名称
identifire: 锁的标识符
Returns:
True: 释放锁成功
False: 释放锁失败
"""
# 锁的名称
lock_names = "lock_name:" + lock_name
# 创建一个管道
pipe = redis_client.pipeline(True)
# 监视锁
pipe.watch(lock_names)
# 检查锁的值是否是获取锁时设置的值
if pipe.get(lock_names).decode() == identifire:
# 锁的值是获取锁时设置的值,执行事务释放锁
pipe.multi()
pipe.delete(lock_names)
pipe.execute()
return True
# 锁的值不是获取锁时设置的值,取消监视
pipe.unwatch()
# 释放锁失败,返回 False
return False
# 模拟加锁解锁的过程
def exec_test(lockname, args):
"""
模拟加锁解锁的过程
Args:
lockname: 锁的名称
args: 获取锁的参数
"""
# 获取锁
identifire = acquire_lock(lockname, args)
print(f'identifire :{identifire}')
# 如果获取到锁,则进行业务逻辑处理
if identifire:
# 模拟业务逻辑处理
time.sleep(3)
# 释放锁
res = release_lock(lockname, identifire)
print(f'释放状态: {res}')
else:
print('获取redis分布式锁失败,其他进程正在使用')
if __name__ == '__main__':
# 循环创建 9 个进程
for i in range(0, 10):
# 创建进程
Process(target=exec_test, args=('id', i)).start()
笔记-python-redis 分布式锁处理
于 2023-08-08 16:52:27 首次发布