一、互斥锁:
那一个抢票的例子来说:一个文件中放一行数据为票的数量 {"number": 1 } 票数为1
from multiprocessing import Process,Lock import json import time def set(i): data_read = json.load(open(‘info_user.txt‘, ‘r‘, encoding=‘utf-8‘)) # 先查看票数,所有人都可以一起查看 time.sleep(2) # 模拟读数据的网络延迟 print(‘%s 查看有%s张票‘ % (i,data_read[‘number‘])) def take(i): data = json.load(open(‘info_user.txt‘, ‘r‘, encoding=‘utf-8‘)) if data[‘number‘]>0: data[‘number‘] = data[‘number‘]-1 time.sleep(2) # 模拟写数据的网络延迟 json.dump(data,open(‘info_user.txt‘,‘w‘,encoding=‘utf-8‘)) print(‘%s 购票成功 ‘ % i) def run(i): set(i) take(i) if __name__ == ‘__main__‘: for i in range(10): p = Process(target=run,args=(i,)) p.start()
结果:会发现所有的人都买到票了,但是票只有一张,多进程效率虽然高但是数据混乱不安全,所以这个互斥锁就是解决数据混乱不安全这个问题的
有1张票 有1张票 有1张票 有1张票 有1张票 有1张票 有1张票 有1张票 有1张票 有1张票 0 购票成功 1 购票成功 2 购票成功 3 购票成功 4 购票成功 5 购票成功 6 购票成功 7 购票成功 8 购票成功 9 购票成功
解决: 这里加上了互斥锁,舍弃效率保证了数据的安全性
from multiprocessing import Process,Lock import json import time def set(i): data_read = json.load(open(‘info_user.txt‘, ‘r‘, encoding=‘utf-8‘)) # 先查看票数,所有人都可以一起查看 time.sleep(2) # 模拟读数据的网络延迟 print(‘%s 查看有%s张票‘ % (i,data_read[‘number‘])) def take(i): data = json.load(open(‘info_user.txt‘, ‘r‘, encoding=‘utf-8‘)) if data[‘number‘]>0: data[‘number‘] = data[‘number‘]-1 time.sleep(2) # 模拟写数据的网络延迟 json.dump(data,open(‘info_user.txt‘,‘w‘,encoding=‘utf-8‘)) print(‘%s 购票成功 ‘ % i) def run(i,lock): set(i) lock.acquire() # 这里也可以用with lock: 相当于lock.acquire(),执行完自代码块自动执行lock.release() take(i) lock.release() if __name__ == ‘__main__‘: lock = Lock() for i in range(10): p = Process(target=run,args=(i,lock)) p.start()
结果:
0 查看有1张票 2 查看有1张票 3 查看有1张票 1 查看有1张票 4 查看有1张票 6 查看有1张票 5 查看有1张票 8 查看有1张票 7 查看有1张票 9 查看有1张票 0 购票成功
二、队列与管道
队列与管道:队列和管道都是将数据存放于内存中,而队列又是基于(管道+锁)实现的,可以让我们从复杂的锁问题中解脱出来,因而队列才是进程间通信的最佳选择
obj = Queue(max_size) 定义方式,max_size是限制队列中的个数
但是:队列中的占用的是内存空间,max_size是受内存大小限制的
队列中放的数据不能是大型的数据
# q.put方法用以插入数据到队列中。 # q.get方法可以从队列读取并且删除一个元素。 from multiprocessing import Queue q = Queue(3) q.put(‘1234‘) q.put([1,2,3,‘e‘]) q.put(1) print(q.full()) # 查看该队列是否已经满了 print(q.get()) print(q.get()) print(q.get()) print(q.empty()) # 是否已经为空 # print(q.get()) # 拿完后队列里没有值了,就死在这里了,阻塞了
原文:https://www.cnblogs.com/whileke/p/11461645.html