簡體   English   中英

Python多處理-進程之間的管道通信

[英]Python multiprocessing - pipe communication between processes

我正在做一個從客戶端傳感器收集數據,處理收集的數據並將其發送回客戶端的項目。 可能有多個客戶端要求同時從我們的服務器接收一些數據,因此我必須實現多處理。 我不能使用線程,因為某些變量必須與客戶端無關。 如果這樣做的話,我的代碼可能會變得非常復雜,以致於無法讀取和升級,我也不想這么做。 因此,我決定使用流程,但是現在在父流程和子流程之間需要剪切一些數據。 經過研究,我發現管道通信可以滿足我的要求。

以下代碼成功地將數據從父級發送到子級Process,子級更新數據並將其發送回父級。 但這僅是因為sleep()函數阻止了父級與子級同時使用管道。

如何對其進行更改,使其具有相同的功能,但是如果沒有sleep()函數,我認為該函數很可能會在將來引起問題?

from multiprocessing import Process, Pipe
import time

def update_data(pipe):
    p_out, p_in = pipe
    L = []
    while True:
        message = p_out.recv()
        if message=='FINISHED':
            break       
        L.append(message)      

    L.append(['new data'])       #updating received data
    writer(L, p_in)              #sending received data to parent Process
    p_in.close()

def writer(i, p_in):
    p_in.send(i)
    p_in.send('FINISHED')

L = ['0' for i in range(10)]     #current data
if __name__=='__main__':
    p_out, p_in = Pipe()
    update_data_process = Process(target=update_data, args=((p_out, p_in),))
    update_data_process.start()    
    writer(L, p_in)              #sending current data to child Process
    time.sleep(3)                #needs to be changed
    while True:
        message = p_out.recv()
        if message != 'FINISHED':
            L = message
        else:
            break
    print(L)
    p_in.close()
    update_data_process.join()

之所以有這個問題,是因為您對待連接的方式就好像它們是simplex一樣 ,但是默認情況下Pipe()返回雙工 (雙向)連接。 這意味着當你調用parent_conn, child_conn = Pipe()你會得到一個連接, 只有家長應使用讀取 寫入 ,並為兒童的另一個這樣的連接對象。 父母孩子僅對他們的連接對象進行操作。

from multiprocessing import Process, Pipe
from datetime import datetime

SENTINEL = 'SENTINEL'


def update_data(child_conn):

    result = []

    for msg in iter(child_conn.recv, SENTINEL):
        print(f'{datetime.now()} child received {msg}')
        result.append(msg)

    print(f'{datetime.now()} child received sentinel')
    result.append(['new data'])
    writer(child_conn, result)
    child_conn.close()


def writer(conn, data):
    conn.send(data)
    conn.send(SENTINEL)


if __name__=='__main__':

    parent_conn, child_conn = Pipe()  # default is duplex!
    update_data_process = Process(target=update_data, args=(child_conn,))
    update_data_process.start()

    data = ['0' for i in range(3)]
    writer(parent_conn, data)

    for msg in iter(parent_conn.recv, SENTINEL):
        print(f'{datetime.now()} parent received {msg}')

    print(f'{datetime.now()} parent received sentinel')
    parent_conn.close()
    update_data_process.join()

示例輸出:

2019-03-12 00:09:52.920375 child received ['0', '0', '0']
2019-03-12 00:09:52.920512 child received sentinel
2019-03-12 00:09:52.920702 parent received [['0', '0', '0'], ['new data']]
2019-03-12 00:09:52.920764 parent received sentinel

Process finished with exit code 0

如果您不熟悉iter(callable, sentinel) ,請看這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM