簡體   English   中英

具有多處理功能的 python 中 IPC 的優雅解決方案

[英]Elegant solution for IPC in python with multiprocessing

我在需要 IPC 的同一台機器上有兩個獨立的進程。 截至目前,我有這個工作解決方案:

服務器.py

#!/usr/bin/python3
from multiprocessing.managers import BaseManager
from multiprocessing import Process, Queue

def do_whatever():
    print('function do whatever, triggered by xyz')
    # do something

def start_queue_server(q):
    class QueueManager(BaseManager): pass

    QueueManager.register('get_queue', callable=lambda:q)
    m = QueueManager(address=('', 55555), authkey=b'tuktuktuk')
    s = m.get_server()
    s.serve_forever()

def main():
    queue = Queue()
    proc = Process(target=start_queue_server, args=(queue,))  
    proc.start()

    while True:
        command = queue.get()
        print('command from queue:', command)

        if command == 'xyz':
            do_whatever()

        # many more if, elif, else statements

if __name__ == "__main__":
    main()

客戶端.py

#!/usr/bin/python3

from multiprocessing.managers import BaseManager

def communicator(command):
    class QueueManager(BaseManager): pass
    QueueManager.register('get_queue')

    m = QueueManager(address=('', 55555), authkey=b'tuktuktuk')
    m.connect()
    queue = m.get_queue()
    queue.put(command)

def main():
    command = ('xyz')
    communicator(command)

if __name__ == "__main__":
    main()
  • 有沒有比解析隊列傳遞的命令然后調用目標 function 更優雅的調用'do_whatever'的方法?
  • 我可以以某種方式傳遞對“do_whatever”的引用並直接從客戶端調用它嗎?
  • 服務器如何將答案(例如 True 或 False)傳達給客戶端? 我嘗試傳遞共享變量而不是隊列 object 但失敗了。 我是否需要使用第二個套接字打開另一個連接來傳遞答案?

我閱讀了 python 文檔,但找不到更多不相關進程的選項。 歡迎提供意見! 歡呼聲

最后,我選擇了一個額外的 Listener

服務器.py

#!/usr/bin/python3
from multiprocessing.managers import BaseManager
from multiprocessing import Process, Queue
from multiprocessing.connection import Client

def do_whatever():
    print('function do whatever, triggered by xyz')
    # do something

def start_queue_server(q):
    class QueueManager(BaseManager): pass

    QueueManager.register('get_queue', callable=lambda:q)
    m = QueueManager(address=('', 55555), authkey=b'tuktuktuk')
    s = m.get_server()
    s.serve_forever()

def talkback(msg, port):
    conn = Client(address=('', port), authkey=b'tuktuktuk')
    conn.send(msg)
    conn.close()

def main():
    queue = Queue()
    proc = Process(target=start_queue_server, args=(queue,))  
    proc.start()

    while True:
        command = queue.get()
        print('command from queue:', command)

        if command[0] == 'xyz':
            do_whatever()
            talkback('aaa', command[1])

        # many more if, elif, else statements

if __name__ == "__main__":
    main()

客戶端.py

#!/usr/bin/python3

from multiprocessing.managers import BaseManager
from multiprocessing.connection import Listener

def communicator(command, talkback=False):
    if talkback:
        listener = Listener(address=('', 0), authkey=b'prusaprinter')
        return_port = listener.address[1]
        command = command + (return_port,)

    class QueueManager(BaseManager): pass
    QueueManager.register('get_queue')

    m = QueueManager(address=('', 55555), authkey=b'tuktuktuk')
    m.connect()
    queue = m.get_queue()
    queue.put(command)

    if talkback:
        conn = listener.accept()
        server_return = conn.recv()
        conn.close()
        listener.close()
        return server_return

def main():
    command = ('xyz')
    communicator(command, True)

if __name__ == "__main__":
    main()

客戶端打開一個可用端口並開始監聽它。 然后它將命令連同上述端口號一起發送到服務器。 服務器執行命令,然后使用端口號向客戶端報告。 收到應答后,客戶端關閉端口。

我在需要 IPC 的同一台機器上有兩個獨立的進程。 截至目前,我有這個工作解決方案:

服務器.py

#!/usr/bin/python3
from multiprocessing.managers import BaseManager
from multiprocessing import Process, Queue

def do_whatever():
    print('function do whatever, triggered by xyz')
    # do something

def start_queue_server(q):
    class QueueManager(BaseManager): pass

    QueueManager.register('get_queue', callable=lambda:q)
    m = QueueManager(address=('', 55555), authkey=b'tuktuktuk')
    s = m.get_server()
    s.serve_forever()

def main():
    queue = Queue()
    proc = Process(target=start_queue_server, args=(queue,))  
    proc.start()

    while True:
        command = queue.get()
        print('command from queue:', command)

        if command == 'xyz':
            do_whatever()

        # many more if, elif, else statements

if __name__ == "__main__":
    main()

客戶端.py

#!/usr/bin/python3

from multiprocessing.managers import BaseManager

def communicator(command):
    class QueueManager(BaseManager): pass
    QueueManager.register('get_queue')

    m = QueueManager(address=('', 55555), authkey=b'tuktuktuk')
    m.connect()
    queue = m.get_queue()
    queue.put(command)

def main():
    command = ('xyz')
    communicator(command)

if __name__ == "__main__":
    main()
  • 有沒有比解析隊列傳遞的命令然后調用目標 function 更優雅的方法來調用“do_whatever”?
  • 我可以以某種方式傳遞對“do_whatever”的引用並直接從客戶端調用它嗎?
  • 來自服務器的答案(例如 True 或 False)如何傳達給客戶端? 我嘗試傳遞共享變量而不是隊列 object 但失敗了。 我是否需要使用第二個套接字打開另一個連接來傳遞答案?

我閱讀了 python 文檔,但找不到更多不相關進程的選項。 歡迎輸入! 干杯singultus

暫無
暫無

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

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