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

2022-09-03 15:48:19 字數 3988 閱讀 4281

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

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

if not q.full():

q.put_nowait("訊息4")

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

if not 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

def write(q):

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

for value in ['a', 'b', 'c']:

print('put %s to queue...' % value)

q.put(value)

time.sleep(random.random())

def read(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...