python—day29 守护进程互斥锁模拟抢票IPC通信机制生产者消费者模型

Posted kermitjam

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python—day29 守护进程互斥锁模拟抢票IPC通信机制生产者消费者模型相关的知识,希望对你有一定的参考价值。

1、守护进程:

什么是守护进程,假如你是皇帝,每日每夜守护你的就是太监,守护进程就相当于太监,当皇帝驾崩后太监也需要陪葬,所以守护进程当父进程销毁时就一起销毁;

 

技术分享图片
 1 from multiprocessing import Process
 2 
 3 import time
 4 
 5 def task(name):
 6 
 7     time.sleep(0.5)
 8     print(%s %name)
 9 
10 
11 if __name__ == __main__:
12     p = Process(target=task,args=(kermit,))
13     p.daemon = True
14     p.start()
15     print(=====>)
View Code

 

技术分享图片

 

2、互斥锁:

强调:必须是lock.acquire()一次,然后lock.release()释放一次,才能继续lock.acquire(),不能连续lock.acquire()

互斥锁 vs join()的区别一:

大前提:二者的原理都是一样,都是将并发编程串行,从而保证有序;

区别:join是按照认为指定的顺序执行,而互斥锁是所有进程平等地竞争;

 1 from multiprocessing import Process,Lock
 2 import time,random
 3 
 4 mutex=Lock()
 5 
 6 def task1(lock):
 7     lock.acquire() #
 8     print(task1:名字是egon)
 9     time.sleep(random.randint(1,3))
10     print(task1:性别是male)
11     time.sleep(random.randint(1,3))
12     print(task1:年龄是18)
13     lock.release()
14 
15 def task2(lock):
16     lock.acquire()
17     print(task2:名字是alex)
18     time.sleep(random.randint(1,3))
19     print(task2:性别是male)
20     time.sleep(random.randint(1,3))
21     print(task2:年龄是78)
22     lock.release()
23 
24 
25 def task3(lock):
26     lock.acquire()
27     print(task3:名字是lxx)
28     time.sleep(random.randint(1,3))
29     print(task3:性别是female)
30     time.sleep(random.randint(1,3))
31     print(task3:年龄是30)
32     lock.release()
33 
34 
35 if __name__ == __main__:
36     p1=Process(target=task1,args=(mutex,))
37     p2=Process(target=task2,args=(mutex,))
38     p3=Process(target=task3,args=(mutex,))
39 
40     # p1.start()
41     # p1.join()
42     # p2.start()
43     # p2.join()
44     # p3.start()
45     # p3.join()
46 
47     p1.start()
48     p2.start()
49     p3.start()

 

3、模拟抢票程序:

 

 1 import json
 2 import time
 3 import random
 4 import os
 5 from multiprocessing import Process,Lock
 6 mutex = Lock()
 7 
 8 def search():
 9     time.sleep(random.randint(1,3))
10     dic = json.load(open(db.json,r,encoding=utf-8))
11     print(%s 剩余票数:%s %(os.getpid(),dic[count]))
12 
13 
14 def get():
15     time.sleep(random.randint(1,2))
16     dic = json.load(open(db.json,r,encoding=utf-8))
17     if dic[count]>0:
18         dic[count] -=1
19         with open(db.json,w,encoding=utf-8) as f:
20             json.dump(dic,f)
21             print(%s购票成功! %os.getpid())
22 
23 def task(lock):
24     search()
25     lock.acquire()
26     get()
27     lock.release()
28 
29 
30 if __name__ == __main__:
31     for i in range(10):
32         p = Process(target=task,args=(mutex,))
33         p.start()

 

 

 

4、IPC通信机制

进程之间通信必须找到一种介质,该介质必须满足

1、是所有进程共享的;

2、必须是内存空间的;

附加:帮我们自动处理好锁的问题

 

技术分享图片
 1 # from multiprocessing import Process,Manager,Lock
 2 # import time
 3 #
 4 # mutex=Lock()
 5 #
 6 # def task(dic,lock):
 7 #     lock.acquire()
 8 #     temp=dic[‘num‘]
 9 #     time.sleep(0.1)
10 #     dic[‘num‘]=temp-1
11 #     lock.release()
12 #
13 # if __name__ == ‘__main__‘:
14 #     m=Manager()
15 #     dic=m.dict({‘num‘:10})
16 #
17 #     l=[]
18 #     for i in range(10):
19 #         p=Process(target=task,args=(dic,mutex))
20 #         l.append(p)
21 #         p.start()
22 #
23 #     for p in l:
24 #         p.join()
25 #     print(dic)
View Code

 

队列:

1、共享的空间;

2、是内存空间;

3、自动帮我们处理好锁的问题

from multiprocessing import Queue

 

1 q=Queue(3)
2 q.put(first)
3 q.put({second:None})
4 q.put()
5 
6 # q.put(4) #阻塞
7 print(q.get())
8 print(q.get())
9 print(q.get())

强调:

 1、队列用来存进程之间沟通的消息,数据量不应该过大

    2、maxsize的值超过的内存限制就变得毫无意义

 

5、生产者消费者模型:

该模型中包含两种重要的类:

1、生产者:将负责造数据的任务比喻成生产者;

2、消费者:接收生产者造出的数据来做进一步的处理,该类任务被比喻成消费者;

 

实现生产者消费者模型三要素

1、生产者

2、消费者

3、队列

 

什么时候用该模型:

程序中出现明显的两类任务,一类任务是负责生产,另一类任务负责处理生产的数据的

 

该模型的好处:

1、实现了生产者与消费者解耦和

2、平衡了生产力与消费力,即生产者可以一直不停地生产,消费者可以不停地处理,因为二者不再直接沟通,而是跟队列沟通;

 1 def counsumer(name,q):
 2     while True:
 3         res = q.get()
 4         time.sleep(random.randint(1,3))
 5         print(%s %s %(name,res))
 6 
 7 def prodicer(name,q,food):
 8     for i in range(5):
 9         time.sleep(random.randint(1,2))
10         res = %s%s %(food,i)
11 
12 if __name__ == __main__:
13     #1、共享的盆
14     q = Queue()
15 
16     #2、生产者们
17     p1 = Process(target=producer,args=(egon1,q,包子))
18     p2 = Process(target=producer,args=(egon2,q,泔水))
19     p3 = Process(target=producer,args=(egon3,q,米饭))
20 
21     #3、消费者们
22     c1 = Process(target=consumer,args=(alex1,q))
23     c2 = Process(target=consumer,args=(alex2,q))
24 
25     p1.start()
26     p2.start()
27     p3.start()
28     c1.start()
29     c2.start()

 

以上是关于python—day29 守护进程互斥锁模拟抢票IPC通信机制生产者消费者模型的主要内容,如果未能解决你的问题,请参考以下文章

进程锁(互斥锁)

进程锁(互斥锁)

Python 开启线程的2中方式,线程VS进程(守护线程互斥锁)

并发编程

python并发编程之多线程守护系列互斥锁生产者消费者模型

python并发编程-进程理论-进程方法-守护进程-互斥锁-01