当前位置:首页 > 技术分析 > 正文内容

Python 多线程之 Redis 分布式锁

ruisui884个月前 (03-10)技术分析12

前言

在很多互联网产品应用中,有些场景需要加锁处理,例如:双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 的累加和这样的一段时间,时间一到主线程结束,但是并没有杀死子线程,子线程依然可以继续执行,直到子线程全部结束,程序退出。

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/2668.html

分享给朋友:

“Python 多线程之 Redis 分布式锁” 的相关文章

gitlab简单搭建与应用

一、gitlab1、简介GitLab是利用Ruby on Rails一个开源的版本管理系统,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目。与Github类似,GitLab能够浏览源代码,管理缺陷和注释。可以管理团队对仓库的访问,它非常易于浏览提交过的版本并提供一个文件历...

HTML5学习笔记三:HTML5语法规则

1.标签要小写2.属性值可加可不加””或”3.可以省略某些标签 html body head tbody4.可以省略某些结束标签 tr td li例:显示效果:5.单标签不用加结束标签img input6.废除的标签font center big7.新添加的标签将在下一HTML5学习笔记中重点阐述。...

尤雨溪:Vue 2生命周期已正式结束,开发团队应迁移至最新版本

IT之家 1 月 2 日消息,Vue.js 作者尤雨溪发文声称,Vue 2 已于 2023 年 12 月 31 日结束生命周期(EOL),目前 Vue 2 已经无法接收到新功能及修复补丁,还在使用 Vue 2 的开发团队应迁移至最新的 Vue 3 版本。据悉,Vue 2.0 最初发布于 2016 年...

Intel Rapid Storage Technology (RST) 20.0.0.1038.3 驱动程序

Intel Rapid Storage Technology (RST) 20.0.0.1038.3 是一种软件包,旨在为支持的操作系统提供高性能的串行 ATA (SATA) 和 SATA RAID 功能。它提供了一种简便的方式来管理和优化硬盘驱动器的性能,并支持 RAID 配置,以提高数据安全性和...

2022年甘肃特岗、三支一扶、西部计划报名通知

报名时间2022年6月7日9:00至6月11日18:00报名网站甘肃省人力资源考试中心(http://ks.rst.gansu.gov.cn)准考证打印时间2022年6月27日9∶00至7月2日9∶00考试时间和地点2022年7月2日考试地点以准考证上指定的地点为准成绩查询时间7月22日左右点击下方...

电工也体会到英文也博大精深了意思一样字母不相同而且还经常遇到

在学习电工电路中,往往和电路图有密切关系,之前老师常说要学会看图,认识电气符号。我觉得这还是不够的。因为在一些电路中存在很多英文字母,它们并不代表电器元件。而是一种电路名称或命名。以下是我在工作中看到过字母常见的意思一样。 如:UVW=RST=ABC=T1T2T3=L1L2L3三相黄绿红 .交流火线...