共享内存
进程间数据是独立的,可以借助于队列或管道实现通信,二者都是基于消息传递的,虽然进程间数据独立,但可以通过Manager实现数据共享
1 from multiprocessing import Process,Manager
2 import os
3
4 def func(name,n,l):
5 l.append(os.getpid())
6 n[name]=os.getpid()
7 if __name__ == '__main__':
8 with Manager() as manager:
9 n=manager.dict({'name':'xiaojie'})
10 l=manager.list(['init',])
11
12 p_l=[]
13 for i in range(5):
14 p=Process(target=func,args=('p{0}'.format(i),n,l))
15 p.start()
16 p_l.append(p)
17 for p in p_l:
18 p.join() #必须有join不然会报错
19 print(n)
20 print(l)
锁
加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行的修改,没错,速度是慢了,牺牲了速度而保证了数据安全。
我们学习了队列,队列是管道+锁实现的,因而我们无需考虑复杂的锁问题。
进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理
所以,就让我们帮文件当做数据库,模拟抢票(Lock互斥锁)
1 #文件db的内容为:{"count":1}
2 #注意一定要用双引号,不然json无法识别
3 from multiprocessing import Process,Lock
4 import json
5 import time
6 import random
7 import os
8
9 def work(filename,lock): #买票
10 # lock.acquire()
11 with lock:
12 with open(filename,encoding='utf-8') as f:
13 dic=json.loads(f.read())
14 # print('剩余票数: %s' % dic['count'])
15 if dic['count'] > 0:
16 dic['count']-=1
17 time.sleep(random.randint(1,3)) #模拟网络延迟
18 with open(filename,'w',encoding='utf-8') as f:
19 f.write(json.dumps(dic))
20 print('%s 购票成功' %os.getpid())
21 else:
22 print('%s 购票失败' %os.getpid())
23 # lock.release()
24
25 if __name__ == '__main__':
26 lock=Lock()
27 p_l=[]
28 for i in range(100):
29 p=Process(target=work,args=('db',lock))
30 p_l.append(p)
31 p.start()
32 for p in p_l:
33 p.join()
34 print('进程结束了')