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