05 Python 并发编程(管道,事件,信号量,进程池)
管道
Conn1,conn2 = Pipe()
Conn1.recv()
Conn1.send()
數據接收一次就沒有了
from multiprocessing import Process,Pipedef f1(conn):from_zhujincheng = conn.recv()print('子進程')print('來自主進程的消息:',from_zhujincheng)if __name__ == '__main__':conn1,conn2 = Pipe() #創建一個管道對象,全雙工,返回管道的兩端,但是一端發送的消息,只能另外一端接收,自己這一端是不能接收的p1 = Process(target=f1,args=(conn2,))p1.start()conn1.send('出來吧')print('主進程')事件
E = Event()? #初識狀態是false
E.wait()? 當事件對象e的狀態為false的時候,在wait的地方會阻塞程序,當對象狀態為true的時候,直接在這個wait地方繼續往下執行
E.set()? 將事件對象的狀態改為true,
E.is_set() 查看狀態
E.clear()? 將事件對象的狀態改為false
from multiprocessing import Process,Evente = Event() #創建事件對象,這個對象的初識狀態為False print('e的狀態是:',e.is_set()) # Falseprint('進程運行到這里了') e.set() #將e的狀態改為True print('e的狀態是:',e.is_set()) # True e.clear() #將e的狀態改為False e.wait() #e這個事件對象如果值為False,就在我加wait的地方等待print('進程過了wait')信號量
S = semphore(數字),內部維護了一個計數器,acquire-1,release+1,為0的時候,其他的進程都要在acquire之前等待
S.acquire()
需要鎖住的代碼
S.release()
import time,random from multiprocessing import Process,Semaphoredef f1(i,s):s.acquire()print('%s男嘉賓到了'%i)time.sleep(random.randint(1,3))s.release()if __name__ == '__main__':s = Semaphore(4) #計數器4,acquire一次減一,為0 ,其他人等待,release加1for i in range(10):p = Process(target=f1,args=(i,s))p.start()進程池
進程的創建和銷毀是很有消耗的,影響代碼執行效率
在有進程池的代碼中,主進程運行結束,進程池里面的任務全部停止,不會等待進程池里面的任務
pl = Pool(數字) ? 這個數字一般是電腦的cpu數
pl的方法:
Map:異步提交任務,并且傳參需要可迭代類型的數據,自帶close和join功能
import time from multiprocessing import Process,Pool#對比多進程和進程池的效率 def f1(n):for i in range(5):n = n + iif __name__ == '__main__':#統計進程池執行100個任務的時間s_time = time.time()pool = Pool(4) pool.map(f1,range(100)) e_time = time.time()dif_time = e_time - s_time#統計100個進程,來執行100個任務的執行時間p_s_t = time.time() #多進程起始時間p_list = []for i in range(100):p = Process(target=f1,args=(i,))p.start()p_list.append(p)[pp.join() for pp in p_list]p_e_t = time.time()p_dif_t = p_e_t - p_s_tprint('進程池的時間:',dif_time)print('多進程的執行時間:',p_dif_t)# 結果: 進程池的時間: 0.40102291107177734 多進程的執行時間: 9.247529029846191 # 可以看出進程池運行效率遠遠大于創建多進程
Close : 鎖住進程池,防止有其他的新的任務在提交給進程池
Join : 等待著進程池將自己里面的任務都執行完
Res = Apply(f1,args=(i,))? #同步執行任務,必須等任務執行結束才能給進程池提交下一個任務,可以直接拿到返回結果res
import time from multiprocessing import Process,Pooldef f1(n):time.sleep(1)return n*nif __name__ == '__main__':pool = Pool(4)for i in range(10):res = pool.apply(f1,args=(i,))print(res)Res_obj = Apply_async(f1,args=(i,))? #異步提交任務,可以直接拿到結果對象,從結果對象里面拿結果,要用get方法,get方法會阻塞程序,沒有拿到結果會一直等待
import time from multiprocessing import Process,Pooldef f1(n):time.sleep(0.5)return n*nif __name__ == '__main__':pool = Pool(4)res_list = []for i in range(10):res = pool.apply_async(f1,args=(i,)) # 不能直接打印返回值,因為直接返回結果對象,進程還沒執行完,結果對象里沒有數據 res_list.append(res)pool.close() pool.join()#打印結果,異步提交之后的結果對象for i in res_list:print(i.get())回調函數:
?Apply_async(f1,args=(i,),callback=function)? #將前面f1這個任務的返回結果作為參數傳給callback指定的那個function函數
import os from multiprocessing import Pool,Processdef f1(n):print('傳入的函數',n)return n*ndef call_back_func(asdf):print('回調函數',asdf)if __name__ == '__main__':pool = Pool(4)res = pool.apply_async(f1,args=(5,),callback=call_back_func)pool.close()pool.join()?
轉載于:https://www.cnblogs.com/a2534786642/p/10267312.html
總結
以上是生活随笔為你收集整理的05 Python 并发编程(管道,事件,信号量,进程池)的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: RedisClient的安装及基本使用
- 下一篇: Python爬虫QQ说说并分析朋友状况
