25.共享内存和锁

共享内存

进程间数据是独立的,可以借助于队列或管道实现通信,二者都是基于消息传递的,虽然进程间数据独立,但可以通过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('进程结束了')

 

posted @ 2017-12-11 20:50  小杰丶  阅读(346)  评论(0)    收藏  举报