背景
當使用多個線程操作任務的時候,如果線程間有需要通信的地方,那么不可避免的要實現到線程間的通信,來互相通知消息,同步任務的執行。

創新互聯建站堅持“要么做到,要么別承諾”的工作理念,服務領域包括:成都網站建設、
成都做網站、企業官網、英文網站、手機端網站、網站推廣等服務,滿足客戶于互聯網時代的
雙湖網站設計、移動媒體設計的需求,幫助企業找到有效的互聯網解決方案。努力成為您成熟可靠的網絡建設合作伙伴!
一.通信
1.線程threading共享內存地址,進程與進程Peocess之間相互獨立,互不影響(相當于深拷貝);
2.在線程間通信的時候可以使用Queue模塊完成,進程間通信也可以通過Queue完成,但是此Queue并非線程的Queue,進程間通信Queue是將數據 pickle 后傳給另一個進程的 Queue,用于父進程與子進程之間的通信或同一父進程的子進程之間通信;
queue
python中的queue模塊其實是對數據結構中棧和隊列這種數據結構的封裝,把抽象的數據結構封裝成類的屬性和方法
使用Queue線程間通信:
1 2 3 4 5 | #導入線程相關模塊
importthreading
importqueue
q=queue.Queue()
使用Queue進程間通信,適用于多個進程之間通信:
1 2 3 4 5 | # 導入進程相關模塊
frommultiprocessingimportProcess
frommultiprocessingimportQueue
q=Queue()
使用Pipe進程間通信,適用于兩個進程之間通信(一對一):
1 2 3 4 5 | # 導入進程相關模塊
frommultiprocessingimportProcess
frommultiprocessingimportPipe
pipe=Pipe()
二.python進程間通信Queue/Pipe使用
python提供了多種進程通信的方式,主要Queue和Pipe這兩種方式,Queue用于多個進程間實現通信,Pipe用于兩個進程的通信;
1.使用Queue進程間通信,Queue包含兩個方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | # !usr/bin/env python
# -*- coding:utf-8 _*-
"""
@Author:何以解憂
@Blog(個人博客地址): shuopython.com
@WeChat Official Account(微信公眾號):猿說python
@Github:www.github.com
@File:python_process_queue.py
@Time:2019/12/21 21:25
@Motto:不積跬步無以至千里,不積小流無以成江海,程序人生的精彩需要堅持不懈地積累!
"""
frommultiprocessingimportProcess
frommultiprocessingimportQueue
importos,time,random
#寫數據進程執行的代碼
defproc_write(q,urls):
print('Process is write....')
forurlinurls:
q.put(url)
print('put %s to queue... '%url)
time.sleep(random.random())
#讀數據進程的代碼
defproc_read(q):
print('Process is reading...')
whileTrue:
url=q.get(True)
print('Get %s from queue'%url)
if__name__=='__main__':
#父進程創建Queue,并傳給各個子進程
q=Queue()
proc_write1=Process(target=proc_write,args=(q,['url_1','url_2','url_3']))
proc_write2=Process(target=proc_write,args=(q,['url_4','url_5','url_6']))
proc_reader=Process(target=proc_read,args=(q,))
#啟動子進程,寫入
proc_write1.start()
proc_write2.start()
proc_reader.start()
#等待proc_write1結束
proc_write1.join()
proc_write2.join()
#proc_raader進程是死循環,強制結束
proc_reader.terminate()
print("mian")
輸出結果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | Processiswrite....
puturl_1toqueue...
Processiswrite....
puturl_4toqueue...
Processisreading...
Geturl_1fromqueue
Geturl_4fromqueue
puturl_5toqueue...
Geturl_5fromqueue
puturl_2toqueue...
Geturl_2fromqueue
puturl_3toqueue...
Geturl_3fromqueue
puturl_6toqueue...
Geturl_6fromqueue
mian
2.使用Pipe進程間通信
Pipe常用于兩個進程,兩個進程分別位于管道的兩端 * Pipe方法返回(conn1,conn2)代表一個管道的兩個端,Pipe方法有duplex參數,默認為True,即全雙工模式,若為FALSE,conn1只負責接收信息,conn2負責發送,Pipe同樣也包含兩個方法:
send() : 發送信息;
recv() : 接收信息;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | frommultiprocessingimportProcess
frommultiprocessingimportPipe
importos,time,random
#寫數據進程執行的代碼
defproc_send(pipe,urls):
#print 'Process is write....'
forurlinurls:
print('Process is send :%s'%url)
pipe.send(url)
time.sleep(random.random())
#讀數據進程的代碼
defproc_recv(pipe):
whileTrue:
print('Process rev:%s'%pipe.recv())
time.sleep(random.random())
if__name__=='__main__':
#父進程創建pipe,并傳給各個子進程
pipe=Pipe()
p1=Process(target=proc_send,args=(pipe[0],['url_'+str(i)foriinrange(10)]))
p2=Process(target=proc_recv,args=(pipe[1],))
#啟動子進程,寫入
p1.start()
p2.start()
p1.join()
p2.terminate()
print("mian")
輸出結果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Processissend:url_0
Processrev:url_0
Processissend:url_1
Processrev:url_1
Processissend:url_2
Processrev:url_2
Processissend:url_3
Processrev:url_3
Processissend:url_4
Processrev:url_4
Processissend:url_5
Processissend:url_6
Processissend:url_7
Processrev:url_5
Processissend:url_8
Processissend:url_9
Processrev:url_6
mian
三.測試queue.Queue來完成進程間通信能否成功?
當然我們也可以嘗試使用線程threading的Queue是否能完成線程間通信,示例代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | frommultiprocessingimportProcess
# from multiprocessing import Queue # 進程間通信Queue,兩者不要混淆
importqueue # 線程間通信queue.Queue,兩者不要混淆
importtime
defp_put(q,*args):
q.put(args)
print('Has put %s'%args)
defp_get(q,*args):
print('%s wait to get...'%args)
print(q.get())
print('%s got it'%args)
if__name__=="__main__":
q=queue.Queue()
p1=Process(target=p_put,args=(q,'p1',))
p2=Process(target=p_get,args=(q,'p2',))
p1.start()
p2.start()
直接異常報錯:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Traceback(mostrecentcalllast):
File"E:/Project/python_project/untitled10/123.py",line38,in<module>
p1.start()
File"G:\ProgramData\Anaconda3\lib\multiprocessing\process.py",line105,instart
self._popen=self._Popen(self)
File"G:\ProgramData\Anaconda3\lib\multiprocessing\context.py",line223,in_Popen
return_default_context.get_context().Process._Popen(process_obj)
File"G:\ProgramData\Anaconda3\lib\multiprocessing\context.py",line322,in_Popen
returnPopen(process_obj)
File"G:\ProgramData\Anaconda3\lib\multiprocessing\popen_spawn_win32.py",line65,in__init__
reduction.dump(process_obj,to_child)
File"G:\ProgramData\Anaconda3\lib\multiprocessing\reduction.py",line60,indump
ForkingPickler(file,protocol).dump(obj)
TypeError:can'tpickle_thread.lockobjects
另外有需要云服務器可以了解下創新互聯cdcxhl.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業上云的綜合解決方案,具有“安全穩定、簡單易用、服務可用性高、性價比高”等特點與優勢,專為企業上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。
網頁標題:python進程使用Queue和Pipe通信-創新互聯
文章路徑:http://vcdvsql.cn/article46/ddgjhg.html
成都網站建設公司_創新互聯,為您提供網站收錄、品牌網站建設、商城網站、搜索引擎優化、云服務器、網站內鏈
廣告
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源:
創新互聯