【问题标题】:Elegant solution for IPC in python with multiprocessing具有多处理功能的python中IPC的优雅解决方案
【发布时间】:2020-07-23 16:30:45
【问题描述】:

我在同一台机器上有两个独立的进程需要 IPC。截至目前,我有这个可行的解决方案:

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

client.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()
  • 有没有比解析队列传递的命令然后调用目标函数更优雅的方式来调用“do_whatever”?
  • 我能否以某种方式传递对“do_whatever”的引用并直接从客户端调用它?
  • 服务器的回答如何,例如对或错,传达给客户?我尝试传递共享变量而不是队列对象,但失败了。我是否需要使用第二个套接字打开另一个连接来传递答案?

我阅读了 python 文档,但找不到更多不相关进程的选项。欢迎输入! 干杯singultus

【问题讨论】:

    标签: python sockets multiprocessing ipc


    【解决方案1】:

    最后,我选择了一个额外的 Listener

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

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

    客户端打开一个可用端口并开始监听它。然后它将命令连同上述端口号一起发送到服务器。服务器执行命令,然后使用端口号向客户端报告。客户端收到应答后关闭端口。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-03
      • 1970-01-01
      相关资源
      最近更新 更多