python并发编程2-进程
生活随笔
收集整理的這篇文章主要介紹了
python并发编程2-进程
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一、信號(hào)量
# 多進(jìn)程中的組件 # ktv # 4個(gè) # 一套資源 同一時(shí)間 只能被n個(gè)人訪問 # 某一段代碼 同一時(shí)間 只能被n個(gè)進(jìn)程執(zhí)行from multiprocessing import Process,Semaphore import time import random def ktv(i,sem):sem.acquire()print('%s走進(jìn)ktv' %i)time.sleep(random.randint(1,5))print('%s走出ktv' % i)sem.release()if __name__ =='__main__':sem=Semaphore(4)for i in range(10):p=Process(target=ktv,args=(i,sem))p.start()運(yùn)行結(jié)果:
二、事件
#事件 from multiprocessing import Event # 一個(gè)信號(hào)樂意是所有的進(jìn)程都進(jìn)入阻塞狀態(tài) # 也可以控制所有的進(jìn)程解除阻塞 #一個(gè)事件被創(chuàng)建之后,默認(rèn)為阻塞狀態(tài) e=Event() print(e.is_set()) #查看一個(gè)事件的狀態(tài)。默認(rèn)被設(shè)置成阻塞 e.set() #將這個(gè)事件的狀態(tài)改為True print(e.is_set()) print(1234556) e.wait() #是依據(jù)e.is_set()的值開決定是否阻塞的 print(123456) e.clear() #將這個(gè)時(shí)間的狀態(tài)改為False print(e.is_set()) e.wait() # 等待事件的信號(hào)變?yōu)門rue print('8'*10)# set 和 clear#分別用來修改一個(gè)事件的狀態(tài) True和False # is_set 用來查看一個(gè)事件的狀態(tài) # wait 是依據(jù)事件的狀態(tài)開決定自己是否在wait處阻塞 # false 是阻塞 True 是不阻塞運(yùn)行結(jié)果:
事件案例之紅綠燈:
from multiprocessing import Event,Process import time import random def cars(e,i):if not e.is_set():print('car%i在等待'%i)e.wait() #阻塞,知道得到一個(gè)時(shí)間狀態(tài)改變成True的信號(hào)print('\033[34mcar%i在通過\033[0m' % i)def light(e):while True:if e.is_set():e.clear()print('\033[31m紅燈亮了\033[0m')else:e.set()print('\033[32m綠燈亮了\033[0m')time.sleep(2) if __name__ =='__main__':e=Event()traffic=Process(target=light,args=(e,))traffic.start()for i in range(10):car=Process(target=cars,args=(e,i))car.start()time.sleep(random.random())運(yùn)行結(jié)果:
三、隊(duì)列
# 隊(duì)列 先進(jìn)先出 #import queue 做不到進(jìn)程間通信 from multiprocessing import Queue import time q=Queue(5) #表示隊(duì)列的大小是5 q.put(1) q.put(2) q.put(3) q.put(4) q.put(5) print(q.full()) #隊(duì)列是否滿了 # q.put(5) # 阻塞,直到取出一個(gè)值,空出一個(gè)地 print(q.get()) print(q.get()) print(q.get()) print(q.get()) print(q.get()) print(q.empty()) # print(q.get()) #阻塞,直到里面有數(shù)據(jù)了 while True:try:q.get_nowait() #阻塞并且會(huì)報(bào)錯(cuò)except:print('隊(duì)列為空')time.sleep(5) # for i in range(6): # q.put(i)運(yùn)行結(jié)果:
隊(duì)列之案例:
from multiprocessing import Queue,Process def produce(q):q.put('hello') def consume(q):print(q.get())if __name__=='__main__':q=Queue()p=Process(target=produce,args=(q,))p.start()c = Process(target=consume, args=(q,))c.start()運(yùn)行結(jié)果:
生產(chǎn)者消費(fèi)者模型
# 隊(duì)列 # 生產(chǎn)者消費(fèi)者模型 #買包子 # 生產(chǎn)者 進(jìn)程 # 消費(fèi)者 進(jìn)程 import time import random from multiprocessing import Queue,Processdef producer(name,food,q):for i in range(6):time.sleep(random.randint(1,3))f='%s生產(chǎn)了%s%s個(gè)'%(name,food,i)print(f)q.put(f)def consumer(q,name):while True:food=q.get()if food == None:print('%s獲取到一個(gè)空了'%name)breakf = '\033[33m%s消費(fèi)了了%s\033[0m' % (name, food)print(f)time.sleep(random.randint(1, 3))if __name__ =='__main__':q=Queue(20)p1=Process(target=producer,args=('Rgon','包子',q))p2 = Process(target=producer, args=('wusir', '泔水', q))p3 = Process(target=consumer, args=(q, 'alex'))p4 = Process(target=consumer, args=(q, 'jinsir'))p1.start()p2.start()p3.start()p4.start()p1.join() # 讓主進(jìn)程感知生產(chǎn)者進(jìn)程的結(jié)束p2.join()q.put(None)q.put(None)運(yùn)行結(jié)果:
可以看到利用手動(dòng)添加p3.join()方式比較繁瑣
生產(chǎn)者消費(fèi)者模型改進(jìn)(JoinableQueue)
import time import random from multiprocessing import Process,JoinableQueue def consumer(q,name):while True:food=q.get()f = '\033[33m%s消費(fèi)了了%s\033[0m' % (name, food)print(f)time.sleep(random.randint(1, 3))q.task_done() # count -1:20 19 18 def producer(name,food,q):for i in range(6):time.sleep(random.randint(1,3))f='%s生產(chǎn)了%s%s個(gè)'%(name,food,i)print(f)q.put(f) #count +1 : 0 1 2 3q.join() # 阻塞,直到感知一個(gè)隊(duì)列中的數(shù)據(jù)全部被執(zhí)行完畢if __name__ =='__main__':q=JoinableQueue(20)p1=Process(target=producer,args=('Rgon','包子',q))p2 = Process(target=producer, args=('wusir', '泔水', q))c1 = Process(target=consumer, args=(q, 'alex'))c2 = Process(target=consumer, args=(q, 'jinsir'))p1.start()p2.start()c1.daemon=True # 設(shè)置為守護(hù)進(jìn)程,主進(jìn)程中的代碼執(zhí)行完畢之后,子進(jìn)程自動(dòng)結(jié)束c2.daemon=Truec1.start()c2.start()p1.join() # 讓主進(jìn)程感知生產(chǎn)者進(jìn)程的結(jié)束p2.join()# 在消費(fèi)者這端:# 每次獲取一個(gè)數(shù)據(jù)# 處理一個(gè)數(shù)據(jù)# 發(fā)送一個(gè)記號(hào):標(biāo)志一個(gè)數(shù)據(jù)被處理成功task_done # 在生產(chǎn)者這端:# 每一次生產(chǎn)一個(gè)數(shù)據(jù)# 且每次生產(chǎn)的數(shù)據(jù)都放在隊(duì)列中# 在隊(duì)列中刻上一個(gè)記號(hào)# 當(dāng)生產(chǎn)者全部生產(chǎn)完畢之后,# join信號(hào):已經(jīng)停止生產(chǎn)數(shù)據(jù)了# 且要等待之前被刻上的記號(hào)都沒消費(fèi)完# 當(dāng)數(shù)據(jù)都被處理完畢后,join阻塞結(jié)束# consumer中把所有的任務(wù)消耗完 # prodecer端的join感知到,停止阻塞 # 所有的producer進(jìn)程結(jié)束 # 主進(jìn)程中的p.join()結(jié)束 # 主進(jìn)程中代碼結(jié)束 # 守護(hù)進(jìn)程(消費(fèi)者進(jìn)程)結(jié)束運(yùn)行結(jié)果:
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的python并发编程2-进程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python random模块seed
- 下一篇: python习题week3