雖然可以用文件共享數據實現進程間通信,但問題是:
1)效率低(共享數據基于文件,而文件是硬盤上的數據)2)需要自己加鎖處理
因此我們最好找尋一種解決方案能夠兼顧:1)效率高(多個進程共享一塊內存的數據)2)幫我們處理好鎖問題。
mutiprocessing模塊為我們提供的基于消息的IPC通信機制:隊列和管道。
1隊列和管道都是將數據存放于內存中
2隊列又是基于(管道+鎖)實現的,可以讓我們從復雜的鎖問題中解脫出來,我們應該盡量避免使用共享數據,盡可能使用消息傳遞和隊列,避免處理復雜的同步和鎖問題,而且在進程數目增多時,往往可以獲得更好的可獲展性
1.隊列(推薦使用)
創建隊列的類(底層就是以管道和鎖定的方式實現):
Queue([maxsize]):創建共享的進程隊列,Queue是多進程安全的隊列,可以使用Queue實現多進程之間的數據傳遞。
參數介紹:
maxsize是隊列中允許最大項數,省略則無大小限制。
應用:
隊列的使用
什么是生產者消費者模式
生產者消費者模式是通過一個容器來解決生產者和消費者的強耦合問題。生產者和消費者彼此之間不直接通訊,而通過阻塞隊列來進行通訊,所以生產者生產完數據之后不用等待消費者處理,直接扔給阻塞隊列,消費者不找生產者要數據,而是直接從阻塞隊列里取,阻塞隊列就相當于一個緩沖區,平衡了生產者和消費者的處理能力。
基于隊列的生產者消費者模型
此時的問題是主進程永遠不會結束,原因是:生產者p在生產完后就結束了,但是消費者c在取空了q之后,則一直處于死循環中且卡在q.get()這一步。
解決方式無非是讓生產者在生產完畢后,往隊列中再發一個結束信號,這樣消費者在接收到結束信號后就可以break出死循環。
生產者在生產完畢后發送結束信號None
注意:結束信號None,不一定要由生產者發,主進程里同樣可以發,但主進程需要等生產者結束后才應該發送該信號
主進程在生產者生產完畢后發送結束信號None
但上述解決方式,在有多個生產者和多個消費者時,應該怎么做呢?有幾個消費者就發幾次信號?
有幾個消費者就應該發送幾次結束信號None
其實我們的思路無非是發送結束信號而已,有另外一種隊列提供了這種機制
#JoinableQueue([maxsize]):這就像是一個Queue對象,但隊列允許項目的使用者通知生成者項目已經被成功處理。通知進程是使用共享的信號和條件變量來實現的。
#參數介紹:
maxsize是隊列中允許最大項數,省略則無大小限制。
#方法介紹:
JoinableQueue的實例p除了與Queue對象相同的方法之外還具有:
q.task_done():使用者使用此方法發出信號,表示q.get()的返回項目已經被處理。如果調用此方法的次數大于從隊列中刪除項目的數量,將引發ValueError異常
q.join():生產者調用此方法進行阻塞,直到隊列中所有的項目均被處理。阻塞將持續到隊列中的每個項目均調用q.task_done()方法為止
以上內容為大家介紹了python進程間通信,希望對大家有所幫助,如果想要了解更多Python相關知識,請關注IT培訓機構:千鋒教育。