使用redis锁处理并发问题,保证多进程仅有一个实例在运行,当运行中的实例down了后其它实例中的一个能顶上来,保证有且仅有一个实例在运行。
import redis r = redis.Redis(...) last_heart = 0 # 记录上一次得到的锁心跳 free_lock_try = 6 # 锁无心跳的最大次数 while not r.setnx('mylock', 1): now_heart = r.get('mylock') print(f"没获取到锁,now_heart={now_heart},last_heart={last_heart},free_lock_try={free_lock_try}") if now_heart == last_heart: free_lock_try = free_lock_try - 1 if free_lock_try == 0: # 锁已经1分钟没有心跳了 old_heart = r.getset('mylock', 1) # 将lock重置为1,并返回set之前的心跳值 if old_heart <p>我们来看看这段程序都解决了并发锁中的哪些问题:</p><p>1、高并发下,多个进程无法同时获取到锁。这里使用的是<a style="color:#f60; text-decoration:underline;" title="redis" href="https://www.php.cn/zt/15737.html" target="_blank">redis</a>.setnx,如果锁已经存在,其他进程是无法重置锁并获取到锁的。另外当多个进程同时发现有锁已经没有心跳了,使用的是redis.getset将心跳重置为1,都能set成功,但是get出来的值多个进程是不一样的,只有真正获取到锁的进程返回的是之前进程的心跳,而其他进程获取到的都是1。</p><p>2、有锁进程正常退出,可以使用atexit注册进程退出函数删除锁,这里也可以不要,不过下次启动得等新的进程等待几次心跳</p><p>3、有锁进程意外退出,退出后心跳不再增加,超过free_lock_try次数后,其他进程会重新设置并获取锁</p><p>4、所有进程全都意外退出,这个问题不是锁来关心的,可以使用supervisor进行守护进程。</p><p>更多redis知识请关注<a href="https://www.php.cn/redis/" target="_blank">redis入门教程</a>栏目。</p>
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END