Python 中通過佇列來實現程序間通訊

2021-10-24 17:34:21 字數 4355 閱讀 3140

python程式中,在程序和程序之間是不共享全域性變數的資料的。

我們來看乙個例子:

from multiprocessing import process

import os

import time

nums =[11

,22]def

work1()

:"""子程序要執行的**"""

print

("in process1 pid=%d ,nums=%s"

%(os.getpid(

), nums)

)for i in

range(3

):time.sleep(1)

print

("in process1 pid=%d ,nums=%s"

%(os.getpid(

), nums)

)def

work2()

:"""子程序要執行的**"""

print

("in process2 pid=%d ,nums=%s"

%(os.getpid(

), nums)

)if __name__ ==

'__main__'

: p1 = process(target=work1)

p1.start(

) p1.join(

) p2 = process(target=work2)

p2.start(

)

程序 p1 裡對全域性變數 nums 迴圈進行處理,程序 p2 將 nums 列印出來,發現 nums 的值沒有變化。

執行結果:

in process1 pid=5788 ,nums=[11, 22]

in process1 pid=5788 ,nums=[11, 22, 0]

in process1 pid=5788 ,nums=[11, 22, 0, 1]

in process1 pid=5788 ,nums=[11, 22, 0, 1, 2]

in process2 pid=11832 ,nums=[11, 22]

通過佇列完成程序間通訊

但是程序(process)之間有時需要通訊,作業系統提供了很多機制來實現程序間的通訊。

可以使用 multiprocessing 模組的 queue 實現多程序之間的資料傳遞。

queue 本身是乙個訊息佇列程式,首先用乙個小例項來演示一下 queue 的工作原理:

from multiprocessing import queue

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

q = queue(

3)

q.put(

"訊息1"

)q.put(

"訊息2"

)print

(q.full())

# false

q.put(

"訊息3"

)print

(q.full())

# true

# 因為訊息佇列已滿下面的try都會丟擲異常

# 第乙個try會等待2秒後再丟擲異常

try:

q.put(

"訊息4"

,true,2

)except

:print

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

% q.qsize())

# 第二個try會立刻丟擲異常

try:

q.put_nowait(

"訊息4"

)except

:print

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

% q.qsize())

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

ifnot q.full():

q.put_nowait(

"訊息4"

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

ifnot q.empty():

for i in

range

(q.qsize())

:print

(q.get_nowait(

))

執行結果:

佇列 queue 的使用說明

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

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

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

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

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

如果 block 使用預設值,且沒有設定 timeout(單位秒),訊息佇列如果為空,此時程式將被阻塞,停在讀取狀態,直到從訊息佇列讀到訊息為止;如果設定了 timeout,則會等待 timeout 秒,若還沒讀取到任何訊息,則丟擲 「queue.empty」 異常。

如果 block 值為 false,訊息列隊如果為空,則會立刻丟擲 「queue.empty」 異常。

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

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

如果 block 使用預設值,且沒有設定 timeout(單位秒),訊息佇列如果已經沒有空間可寫入,此時程式將被阻塞,停在寫入狀態,直到從訊息佇列騰出空間為止;如果設定了timeout,則會等待 timeout 秒,若還沒空間,則丟擲 「queue.full」 異常。

如果 block 值為 false,訊息佇列如果沒有空間可寫入,則會立刻丟擲 「queue.full」 異常。

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

queue例項

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

from multiprocessing import process, queue

import os

import time

import 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(

)print(''

)print

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

)

執行結果:

Python 中通過佇列來實現程序間通訊

python程式中,在程序和程序之間是不共享全域性變數的資料的。我們來看乙個例子 from multiprocessing import process import os import time nums 11,22 def work1 子程序要執行的 print in process1 pid ...

Unity中通過PlayerPrefs進行資料儲存

在unity中儲存資料也是通過鍵值對的方式來進行。主要通過playerprefs來完成。通過playerprefs可以用來儲存和訪問玩家的偏好設定。在mac os x中,playerprefs的資料儲存在 library preferences資料夾中,以unity.company name pro...

在Sqlite中通過Replace來實現插入和更新

你可能在批量處理乙個事務的時候,想要批量插入一系列的資料,但是這些資料當新增完一次之後,重新新增的時候,你不想要重新新增,只是想將原有的資料進行更新,例如 我想要通過excel將一系列的圖書匯入到資料庫中,而這些圖書在你下一次編輯之後,重新匯入,只是對原有的資料進行修改。以上是乙個業務的場景。在ms...