网站首页 > 技术文章 正文
前言
在很多互联网产品应用中,有些场景需要加锁处理,例如:双11秒杀,全局递增ID,楼层生成等等。
大部分的解决方案是基于 DB 实现的,Redis 为单进程单线程模式,采用队列模式将并发访问变成串行访问,且多客户端对 Redis 的连接并不存在竞争关系。
其次 Redis 提供一些命令SETNX,GETSET,可以方便实现分布式锁机制。
Python代码实现
import time
import redis
import threading
#使用连接池方式连接redis
redis_pool=redis.ConnectionPool(host="127.0.0.1",port=6379)
redis_conn=redis.Redis(connection_pool=redis_pool)
#定义redis类
class RedisLock():
def __init__(self):
self.redis_conn = redis_conn
print("init the redis connection")
#获取锁
def get_lock(self,name,value):
while True:
# set(name, value, ex=None, px=None, nx=False, xx=False)
# nx - 如果设置为True,则只有name不存在时,当前set操作才执行
# ex - 过期时间(秒)
result=self.redis_conn.set(name,value,nx=True,ex=3)
# print(result)
if(result):
# 获取到result后就终止while循环
break
# time.sleep(0.5)
#释放锁
def release_lock(self,name,value):
#获取原name key对应的value
old_value = redis_conn.get(name)
print("--------------------------------the key =%s ;the name=%s"%(name,old_value))
#判断原value 与 要释放的值是否相同
if(old_value == value):
#相同就从redis里面释放
self.redis_conn.delete(name)
print("release the lock is success")
def redis_lock_test(lock,name,value):
try:
print("% --start to work"%name)
print("% --ready get the lock and execute lock operation"%name)
lock.get_lock(name,value)#这里是获取锁操作
print("% --get the lock and continue to operation"%name)
except Exception as e:
print("the exception is:%s"%str(e))
finally:
print("% --ready release the lock"%name)
lock.release_lock(name,value)#最终必须释放锁操作
print("% --release the lock is over"%name)
if __name__ == '__main__':
start_time=time.time()
rs=RedisLock()
tasks=[]
for i in range(1,3):
# 创建线程
t = threading.Thread(target=redis_lock_test(rs,"task-name%"%i,"lock%d"%i))
# 将创建的线程放入列表
tasks.append(t)
# 启动线程
t.start()
#这里没有设置守护线程且没有设置join函数的timeout参数时,主线程将会一直等待,直到子线程全部结束,主线程才结束,程序退出
[t.join() for t in tasks]
print("total waster time is:",time.time()-start_time)
注意:
1. thread.setDaemon(True) 当设置守护线程 join 函数的参数 timeout=2 时,主线程将会等待多个子线程 timeout 的累加和这样的一段时间,时间一到,主线程结束,杀死未执行完的子线程,程序退出。
2. 当没有设置守护线程且 join 函数的参数 timeout=2 时,主线程将会等待多个子线程 timeout 的累加和这样的一段时间,时间一到主线程结束,但是并没有杀死子线程,子线程依然可以继续执行,直到子线程全部结束,程序退出。
猜你喜欢
- 2025-04-29 Python打包方式PyInstaller、cx_Freeze、Py2exe、setuptools用法
- 2025-04-29 Python的hasattr() getattr() setattr() 函数使用方法详解
- 2025-04-29 python集合set() 数据增册改查统计序循常用方法和数学计算
- 2025-04-29 微软承认Windows 10新BUG:错误显示没有网络连接
- 2025-04-29 一个开源免费高颜值的轻量级商业智能BI平台Superset 介绍
- 2025-04-29 Python小案例46-集合的定义和创建
- 2025-04-29 Python基础知识之集合(set)中交集、并集、差集运算
- 2025-04-29 Python Set Difference():完整指南
- 2025-04-29 简单学Python——内置函数24——set()函数
- 2025-04-29 容易忽略的数据类型:集合(set)
- 258℃Python短文,Python中的嵌套条件语句(六)
- 258℃python笔记:for循环嵌套。end=""的作用,图形打印
- 257℃PythonNet:实现Python与.Net代码相互调用!
- 252℃Python操作Sqlserver数据库(多库同时异步执行:增删改查)
- 252℃Python实现字符串小写转大写并写入文件
- 108℃原来2025是完美的平方年,一起探索六种平方的算吧
- 91℃Python 和 JavaScript 终于联姻了!PythonMonkey 要火?
- 83℃Ollama v0.4.5-v0.4.7 更新集合:Ollama Python 库改进、新模型支持
- 最近发表
- 标签列表
-
- python中类 (31)
- python 迭代 (34)
- python 小写 (35)
- python怎么输出 (33)
- python 日志 (35)
- python语音 (31)
- python 工程师 (34)
- python3 安装 (31)
- python音乐 (31)
- 安卓 python (32)
- python 小游戏 (32)
- python 安卓 (31)
- python聚类 (34)
- python向量 (31)
- python大全 (31)
- python次方 (33)
- python桌面 (32)
- python总结 (34)
- python浏览器 (32)
- python 请求 (32)
- python 前端 (32)
- python验证码 (33)
- python 题目 (32)
- python 文件写 (33)
- python中的用法 (32)