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基礎知識匯總

TAG:Python | Python入门 |