Python程序通訊之Queue

2021-10-09 03:20:18 字數 4312 閱讀 8283

前言:process之間有時需要通訊,作業系統提供了很多機制來實現程序間的通訊。本博文主要講解:程序間通訊的queue

python多程序中的multiprocessing

python多程序中的fork

python併發程式設計之程序池

我們可以使用multiprocessing模組的queue實現多程序之間的資料傳遞,queue本身是乙個訊息列隊程式,首先用乙個小例項來演示一下queue的工作原理:

from multiprocessing import queue

q = queue(3)

# 初始化乙個queue物件,最多可接收三條put訊息

q.put(

"訊息1"

)q.put(

"訊息2"

)print

(q.full())

# false

q.put(

"訊息3"

)print

(q.full())

# true

# 因為訊息列隊已滿下面的try都會丟擲異常,第乙個try會等待2秒後再丟擲異常,第二個try會立刻丟擲異常

try:

q.put(

"訊息4"

,true,2

)except

:print

("訊息列隊已滿,現有訊息數量:%s"

% q.qsize())

try:

q.put_nowait(

"訊息4"

)except

:print

("訊息列隊已滿,現有訊息數量:%s"

% q.qsize())

# 推薦的方式,先判斷訊息列隊是否已滿,再寫入

ifnot q.full():

q.put_nowait(

"訊息4"

)# 讀取訊息時,先判斷訊息列隊是否為空,再讀取

初始化queue()物件時(例如:q = queue()),若括號中沒有指定最大可接收的訊息數量或數量為負值,那麼就代表可接受的訊息數量沒有上限(直到記憶體的盡頭)。

queue.qsize():返回當前佇列包含的訊息數量;

queue.empty():如果隊列為空,返回true,反之false ;

queue.full():如果佇列滿了,返回true,反之false;

queue.get([block[, timeout]]):獲取佇列中的一條訊息,然後將其從列隊中移除,block預設值為true;

queue.get_nowait():相當queue.get(false);

queue.put(item,[block[, timeout]]):將item訊息寫入佇列,block預設值為true;

queue.put_nowait(item):相當queue.put(item, false);

我們以queue為例,在父程序中建立兩個子程序,乙個往queue裡寫資料,乙個從queue裡讀資料:

from multiprocessing import process, queue

import os, time, random

# 寫資料程序執行的**:

defwrite

(q):

for value in

['a'

,'b'

,'c']:

print

("put %s to queue..."

% value)

q.put(value)

time.sleep(random.random())

# 讀資料程序執行的**:

defread

(q):

while

true:if

not q.empty():

value = q.get(

true

)print

("get %s from queue."

% value)

time.sleep(random.random())

else

:break

if __name__==

'__main__'

:# 父程序建立queue,並傳給各個子程序:

q = queue(

) pw = process(target=write, args=

(q,)

) pr = process(target=read, args=

(q,)

)# 啟動子程序pw,寫入:

pw.start(

)# 等待pw結束:

pw.join(

)# 啟動子程序pr,讀取:

pr.start(

) pr.join(

)# pr程序裡是死迴圈,無法等待其結束,只能強行終止:

print

("所有資料都寫入並且讀完"

如果要使用pool建立程序池,就需要使用multiprocessing.manager()中的queue(),而不是multiprocessing.queue(),否則會得到一條如下的錯誤資訊:

runtimeerror: queue objects should only be shared between processes through inheritance.
下面的例項演示了程序池中的程序如何通訊:

# 修改import中的queue為manager

from multiprocessing import manager, pool

import os, time, random

defreader

(q):

print

("reader啟動(%s),父程序為(%s)"

%(os.getpid(

), os.getppid())

)for i in

range

(q.qsize())

:print

("reader從queue獲取到訊息:%s"

% q.get(

true))

defwriter

(q):

print

("writer啟動(%s),父程序為(%s)"

%(os.getpid(

), os.getppid())

)for i in

"dongge"

: q.put(i)

if __name__ ==

"__main__"

:print

("(%s) start"

% os.getpid())

q = manager(

).queue(

)# 使用manager中的queue來初始化

po = pool(

)# 使用阻塞模式建立程序,這樣就不需要在reader中使用死迴圈了,可以讓writer完全執行完成後,再用reader去讀取

python之《棧stack和佇列queue》

棧和佇列是兩種常用的,重要的資料結構。棧和佇列是限定插入和刪除只能在表的 端點 進行的線性表。棧 特點 後進先出 1,建立棧 借助列表 stack list print stack 2,判斷是否為空棧 stack list print stack if not stack print 為空棧 els...

程序通訊之管道通訊

管道通訊有乙個特點 通訊是半雙工的,即管道的一端只能讀或者只能寫 管道通訊可以分為 匿名管道通訊和命名管道通訊兩種 1.匿名管道通訊 適合用於父子程序間的通訊 include include include 匿名管道通訊,本機父子程序通訊方式 int main else waitpid pid,nu...

程序通訊之pipe通訊

管道是一種最基本的ipc機制,由pipe函式建立 include int pipe int filedes 2 管道作用於有血緣關係的程序之間,通過fork來傳遞呼叫pipe函式時在核心中開闢一塊緩衝區 稱為管道 用於通訊,它有乙個讀端乙個寫端,然後通過filedes引數傳出給使用者程式兩個檔案描述...