Python篇-多進程與協程的理解與使用
分享文章,原文:Python多進程與協程的理解與使用
一 : 科普一分鐘
- 儘管
進程
間是獨立存在的,不能相互訪問彼此的數據,但是在python
中卻存在進程
間的通信方法,來幫助我們可以利用多核CPU
也能共享
數據. - 對於
多線程
其實也是存在一些缺點的,不是任何場景我們都用多線程
來完成並發
處理任務,因為CPU操作線程
,所以線程多了,對於計算機的資源消耗是十分嚴重的,多線程
適合IO
操作密集的任務,那麼怎麼辦呢,協程
的出現幫我們解決了這個問題 ,協程
是比線程更小的一個單位,但是它的作用卻不容忽視.
二 : 多進程
1. 多進程簡單了解 :
進程之間是獨立的,是操作系統自己來維護和管理的,python
通過C介面起了一個進程,多進程可以充分的利用多核CPU
2. 多進程的創建 :
import multiprocessingimport time# 子進程執行方法def run(person): time.sleep(2) print(person)#循環創建 10個子進程for i in range(10):#創建子進程實例 p = multiprocessing.Process(target=run,args=("雪芙 %s" %i ,))#運行子進程 p.start()
3. 多進程間的通信 :
進程間獨立,如果想相互訪問,就必須有一個中間翻譯,下面提供了幾種進程間通信的方法
- 進程Queue
from multiprocessing import Process,Queue# import queue#子進程,內存獨立,相當於數據的傳遞def f(subQueue): subQueue.put("雪芙")if __name__ == "__main__": #進程Queue q = Queue() #創建進程 p = Process(target=f,args=(q,)) #執行進程 p.start() print(q.get())
解析 :
Queue
通信,相當於父進程賦值了一個Queue
給子進程,子進程在這個Queue
放好數據後,序列化一個中間翻譯,然後在反序列化返回給父進程,因為進程之間內存獨立,不能傳遞對象
傳遞的其實就是序列化
的數據
- Pipe多進程還有一種數據傳遞方式叫
管道
原理和Queue
相同
# Author:TianTianBabyfrom multiprocessing import Process,Pipe#子進程執行方法def f(Subconn): Subconn.send("吃了嗎") print("來自父親的問候 : ",Subconn.recv()) Subconn.close()if __name__ == "__main__":#創建管道兩端 parent_conn,child_conn = Pipe()#創建子進程 p = Process(target=f,args=(child_conn,)) p.start() print("來自兒子的問候 :",parent_conn.recv()) parent_conn.send("你好啊") p.join()
4. 進程鎖
雖然內存獨立,但是即使是列印也會造成列印數據錯誤,為了防止進程間搶屏幕列印輸出,加了進程鎖
from multiprocessing import Process,Lock#子進程執行方法def f(lock,num): lock.acquire() print("tztztz",num) lock.release()if __name__ == "__main__": lock = Lock()#循環創建100個子進程 for num in range(100): Process(target=f,args=(lock,num)).start()
5. 進程池
創建一個子進程
相當於copy一份父進程
內存數據,為了防止頻繁創建,導致內存不足,所以有了進程池
作為限制.
# Author:TianTianBabyfrom multiprocessing import Process,Poolimport time,osdef son(i): time.sleep(2) return i+100def Back(arg): print("你好完成")#允許進程池同時放入5個進程pool = Pool(processes=3)for i in range(10): #並行 callback 回調(主進程調用的) pool.apply_async(func=son,args=(i,),callback=Back) #並行 # pool.apply_async(func=son, args=(i,)) #串列 # pool.apply(func=son,args=(i,))print("end")#先關閉進程池再joinpool.close()#進程池中進程執行完畢再關閉,如果注釋,那麼程序直接關閉pool.join()
三 : 協程
1. 協程的簡單了解 :
協程
又稱微線程
,coroutne
,協程
是一種用戶態的輕量級線程
通俗點講就是周末我在家裡休息,假如我先洗漱,再煮飯,再下載電影看會很慢,用了協程
的效果就好比,我在下載電影的時候去點火煮飯,此時我馬上洗漱,等我洗漱好了,飯也好了,吃完飯了,電影下好了,我可以看了.
2. 協程的創建和使用 :
gevent
是一個三方庫,可以輕鬆通過gevent
實現並發同步或者非同步編程.
# Author:TianTianBabyimport gevent#函數1def first(): print("運行 1") gevent.sleep(2) print("回到1")#精確的文本內容切換到 ..#函數2def second(): print("運行2") gevent.sleep(1) print("回到2")#函數3def third(): print("運行3") gevent.sleep(0) print("回到3")#創建並添加寫成任務gevent.joinall([gevent.spawn(first), #生成 gevent.spawn(second), gevent.spawn(third)])
解析:嘗試運行發現,運行時間為Sleep
最長的時間,也就是說協程
能繞過IO,進行執行,極大的提高了效率.
IO(從硬碟上讀一塊數據,從網路讀數據,從內存里讀一塊數據) 操作不佔用CPU,計算佔用CPU
3. 協程簡單爬網頁 :
# Author:TianTianBabyfrom urllib import requestimport sslimport geventfrom gevent import monkey#把當前程序的所有的IO操作 單獨做上標記monkey.patch_all()ssl._create_default_https_context = ssl._create_unverified_contextdef f(url): print("GET:%s" %url) resp = request.urlopen(url) print(resp) data = resp.read() f = open("pa.html","wb") f.write(data) f.close() print("%d bytes received from %s" %(len(data),url))gevent.joinall([gevent.spawn(f,"http://www.jianshu.com/"), gevent.spawn(f,"http://www.iconfont.cn/"), gevent.spawn(f,"http://www.cocoachina.com/"), ])
4. 協程實現socketServer:
通過協程,我們可以寫出一個socketServer
,真正socketServer
的底層是用多線程來實現,我們用寫成寫出的效率很高,而且非常節省內存
import sysimport socketimport timeimport geventfrom gevent import socket,monkeymonkey.patch_all()def server(port): s = socket.socket() s.bind(("localhost",port)) s.listen(500) while True: cli,addr = s.accept() #交給協程處理 gevent.spawn(handle_request,cli)def handle_request(conn): try: while True: data = conn.recv(1024) print("recv:",data) conn.send(data) if not data: conn.shutdown(socket.SHUT_WR) except Exception as ex: print(ex) finally: conn.close()if __name__ == "__main__": server(9001)
四 : 總結
- 協程的優點1 : 線程在單線程下切換,減少資源消耗2 : 無需原子操作控制流,簡化編程模型3 : 高並發,高擴展,低成本.
- 無論是
多進程
,多線程
還是協程
在不同的場景用不同的模型才能高效的完成任務.
你想更深入了解學習Python知識體系,你可以看一下我們花費了一個多月整理了上百小時的幾百個知識點體系內容:
【超全整理】《Python自動化全能開發從入門到精通》筆記全放送
推薦閱讀:
※如何踏上人工智慧之路(機器學習篇)
※【強烈推薦】十三個鮮為人知的大數據學習網站
※普通人為什麼要學習Python?
※Python 求職 Top10 城市,來看看是否有你所在的城市
※Python基礎知識匯總