基于Python怎样实现互斥锁LOCK
Admin 2022-07-25 群英技术资讯 342 次浏览
应用场景举例描述: Lock 互斥锁:举例说明-C有三个同事同时需要上厕所,但是只有一间厕所,将同事比作进程,多个进程并打抢占一个厕所,我们要保证顺序优先, 一个个来,那么就必须串行,先到先得,有人使用了,就锁住,结束后剩余的人继续争抢
模拟三个同事抢占厕所
from multiprocessing import Process from multiprocessing import Lock import time import random def task1(p, lock): # 上锁 lock.acquire() print(f'{p} 开始排泄') time.sleep(random.randint(1, 3)) print(f'{p} 排泄结束') # 解锁 lock.release() def task2(p, lock): lock.acquire() print(f'{p} 开始排泄') time.sleep(random.randint(1, 3)) print(f'{p} 排泄结束') lock.release() def task3(p, lock): lock.acquire() print(f'{p} 开始排泄') time.sleep(random.randint(1, 3)) print(f'{p} 排泄结束') lock.release() if __name__ == '__main__': # 实例化一个锁对象 mutex = Lock() # 将锁以参数的形式传入进程对象 p1 = Process(target=task1, args=('task1', mutex,)) p2 = Process(target=task2, args=('task2', mutex,)) p3 = Process(target=task3, args=('task3', mutex,)) p1.start() p2.start() p3.start()
执行结果:
# 输出结果:三个进程开始争抢互斥锁,先抢到的先执行,执行结束后,释放掉锁,剩下的继续争抢
task1 开始排泄
task1 排泄结束
task2 开始排泄
task2 排泄结束
task3 开始排泄
task3 排泄结束
1、 注意:
2、 lock和join比较:
上面的代码虽然起到了先进先出,一进一出的效果,但是并不完美。总所周知,我们上厕所是谁先抢到谁先上,并不是说按照代码里start()顺序执行。应该由先抢占到的进程限制性才更合理。
from multiprocessing import Process from multiprocessing import Lock import time import random import sys def task1(p, lock): # 上锁 lock.acquire() print(f'{p} 开始打印') time.sleep(random.randint(1, 3)) print(f'{p} 打印结束') # 解锁 lock.release() def task2(p, lock): lock.acquire() print(f'{p} 开始打印') time.sleep(random.randint(1, 3)) print(f'{p} 打印结束') lock.release() def task3(p, lock): lock.acquire() print(f'{p} 开始打印') time.sleep(random.randint(1, 3)) print(f'{p} 打印结束') lock.release() if __name__ == '__main__': slock = Lock() for i in range(1,4): p = Process(target=getattr(sys.modules[__name__], f'task{i}'), args=(f'task{i}', slock)) p.start()
输出结果:
task2 开始打印
task2 打印结束
task3 开始打印
task3 打印结束
task1 开始打印
task1 打印结束
semaphore(信号量):用来控制对共享资源的访问数量,可以控制同一时刻并发的进程数
信号量: 也是一把锁,但是不保证数据安全性,同时开启多个线程,但是规定了同时并发执行的上限,后面走多少,进多少。(用于控制并发数量)
# 举例说明:一间厕所有5个坑位,最多只能同时有5个人上厕所,当前时刻有20个人想上厕所,但是只能让5个人进去,然后出来多少个,才能进去多少个上厕所 # 从一个模块引用多个功能的时候,用逗号隔开 from threading import Semaphore, Thread, currentThread import time import random sem = Semaphore(3) # 并发执行数设置为5 def task(): sem.acquire() print(f'{currentThread().name}') time.sleep(random.randint(1,3)) sem.release() if __name__ == '__main__': for i in range(20): t = Thread(target=task) t.start()
执行结果:首次并发量是3,后面先抢到锁先执行
Thread-1
Thread-2
Thread-3Thread-4
Thread-5Thread-6
Thread-7Thread-8
Process finished with exit code 0
import multiprocessing import time def worker(s, i): s.acquire() print(time.strftime('%Y-%m-%d %H:%M:%S'), multiprocessing.current_process().name + " 抢占并获得锁,运行") time.sleep(i) print(time.strftime('%Y-%m-%d %H:%M:%S'), multiprocessing.current_process().name + " 运行结束,释放锁") s.release() if __name__ == '__main__': s = multiprocessing.Semaphore(2) for i in range(8): p = multiprocessing.Process(target=worker, args=(s, 1)) p.start()
执行结果:
在执行结果输出的终端,每阻塞一次,按下回车键,可以更加清晰的看出进程的并发执行。
由下面执行结果可以看出,同一时刻,有两个进程在执行
2021-05-18 22:50:37 Process-1 抢占并获得锁,运行
2021-05-18 22:50:37 Process-2 抢占并获得锁,运行2021-05-18 22:50:38 Process-1 运行结束,释放锁
2021-05-18 22:50:38 Process-3 抢占并获得锁,运行
2021-05-18 22:50:38 Process-2 运行结束,释放锁
2021-05-18 22:50:38 Process-4 抢占并获得锁,运行2021-05-18 22:50:39 Process-3 运行结束,释放锁
2021-05-18 22:50:39 Process-5 抢占并获得锁,运行
2021-05-18 22:50:39 Process-4 运行结束,释放锁
2021-05-18 22:50:39 Process-6 抢占并获得锁,运行2021-05-18 22:50:40 Process-5 运行结束,释放锁
2021-05-18 22:50:40 Process-7 抢占并获得锁,运行
2021-05-18 22:50:40 Process-6 运行结束,释放锁
2021-05-18 22:50:40 Process-8 抢占并获得锁,运行2021-05-18 22:50:41 Process-7 运行结束,释放锁
2021-05-18 22:50:41 Process-8 运行结束,释放锁Process finished with exit code 0
多个进程并发执行,提高资源利用率,从而提高效率,但是有时候我们需要在某一时刻只能有一个进程访问某个共享资源的话,就需要使用锁LOCK
import multiprocessing import time def task1(): n = 4 while n > 1: print(f'{time.strftime("%Y-%M-%d %H:%M:%S")} task1 输出信息') time.sleep(1) n -= 1 def task2(): n = 4 while n > 1: print(f'{time.strftime("%Y-%M-%d %H:%M:%S")} task2 输出信息') time.sleep(1) n -= 1 def task3(): n = 4 while n > 1: print(f'{time.strftime("%Y-%M-%d %H:%M:%S")} task3 输出信息') time.sleep(1) n -= 1 if __name__ == '__main__': p1 = multiprocessing.Process(target=task1) p2 = multiprocessing.Process(target=task2) p3 = multiprocessing.Process(target=task3) p1.start() p2.start() p3.start()
执行结果:
2021-59-18 22:59:46 task1 输出信息
2021-59-18 22:59:46 task2 输出信息
2021-59-18 22:59:46 task3 输出信息2021-59-18 22:59:47 task1 输出信息
2021-59-18 22:59:47 task2 输出信息
2021-59-18 22:59:47 task3 输出信息2021-59-18 22:59:48 task1 输出信息
2021-59-18 22:59:48 task2 输出信息
2021-59-18 22:59:48 task3 输出信息Process finished with exit code 0
有两种加锁方式:首先将 lock = multiprocessing.Lock() 生成锁对象lock
import multiprocessing import time def task1(lock): with lock: n = 4 while n > 1: print(f'{time.strftime("%Y-%M-%d %H:%M:%S")} task1 输出信息') time.sleep(1) n -= 1 def task2(lock): lock.acquire() n = 4 while n > 1: print(f'{time.strftime("%Y-%M-%d %H:%M:%S")} task2 输出信息') time.sleep(1) n -= 1 lock.release() def task3(lock): lock.acquire() n = 4 while n > 1: print(f'{time.strftime("%Y-%M-%d %H:%M:%S")} task3 输出信息') time.sleep(1) n -= 1 lock.release() if __name__ == '__main__': lock = multiprocessing.Lock() p1 = multiprocessing.Process(target=task1, args=(lock,)) p2 = multiprocessing.Process(target=task2, args=(lock,)) p3 = multiprocessing.Process(target=task3, args=(lock,)) p1.start() p2.start() p3.start()
执行结果
2021-11-18 23:11:37 task1 输出信息
2021-11-18 23:11:38 task1 输出信息
2021-11-18 23:11:39 task1 输出信息
2021-11-18 23:11:40 task2 输出信息
2021-11-18 23:11:41 task2 输出信息
2021-11-18 23:11:42 task2 输出信息
2021-11-18 23:11:43 task3 输出信息
2021-11-18 23:11:44 task3 输出信息
2021-11-18 23:11:45 task3 输出信息
Process finished with exit code 0
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
字典是Python必用且常用的数据结构,本文主要为大家梳理了一下常用的字典操作:初始化、合并字典、字典转Pandas等,需要的可以参考一下
这篇文章主要介绍了利用Python编写一个经典小游戏的合集,包括:贪吃蛇,扫雷,俄罗斯方块,五子棋。感兴趣的小伙伴可以跟随小编一起学习一下
这篇文章主要介绍了pycharm终端解释器与Python解释器配置,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
如果想要得心应手的去使用python语言,那么对于python的字符串大小一定要认真了解,下面给大家整理关于python字符串大小用法和示例,便于大家理解!
Pandas 是python的一个数据分析包,最初由AQR Capital Management于2008年4月开发,并于2009年底开源出来,目前由专注于Python数据包开发的PyData开发team继续开发和维护,今天通过本文给大家介绍Python Pandas的简单使用教程,感兴趣的朋友一起看看吧
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008