无阻塞多处理.connection.Listener?

2024-04-19 08:10:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用多处理.connection.Listener对于流程之间的沟通,这对我来说是一种魅力。现在我真的很喜欢我的主循环在客户端的命令之间执行其他操作。不幸的是侦听器.accept()在与客户端进程建立连接之前阻止执行。在

有没有一种简单的方法来管理多处理.connection?暂停?或者我应该使用专用线程?在

    # Simplified code:

    from multiprocessing.connection import Listener

    def mainloop():
        listener = Listener(address=(localhost, 6000), authkey=b'secret')

        while True:
            conn = listener.accept() # <---  This blocks!
            msg = conn.recv() 
            print ('got message: %r' % msg)
            conn.close()

Tags: 方法命令客户端进程msg流程simplifiedconnection
2条回答

我自己没有使用侦听器对象-对于此任务,我通常在以下链接使用multiprocessing.Queue;doco:

https://docs.python.org/2/library/queue.html#Queue.Queue

这个对象可以用一个很好的API在Python进程之间发送和接收任何可pickle的对象;我想您最感兴趣的是:

  • 过程A
    • .put('some message')
  • 过程B
    • .get_nowait() # will raise Queue.Empty if nothing is available- handle that to move on with your execution

唯一的限制是,您需要在某个时刻控制两个流程对象,以便能够将队列分配给它们—如下所示:

import time
from Queue import Empty
from multiprocessing import Queue, Process


def receiver(q):
    while 1:
        try:
            message = q.get_nowait()
            print 'receiver got', message
        except Empty:
            print 'nothing to receive, sleeping'
            time.sleep(1)


def sender(q):
    while 1:
        message = 'some message'
        q.put('some message')
        print 'sender sent', message
        time.sleep(1)


some_queue = Queue()

process_a = Process(
    target=receiver,
    args=(some_queue,)
)

process_b = Process(
    target=sender,
    args=(some_queue,)
)

process_a.start()
process_b.start()

print 'ctrl + c to exit'
try:
    while 1:
        time.sleep(1)
except KeyboardInterrupt:
    pass

process_a.terminate()
process_b.terminate()

process_a.join()
process_b.join()

队列是很好的,因为您实际上可以为同一队列对象拥有任意多个消费者和生产者(方便分发任务)。在

我应该指出,仅仅在进程上调用.terminate()是不好的形式-您应该使用新的消息传递系统来传递关闭消息或类似的消息。在

多处理模块附带了一个很好的特性Pipe()。这是在两个进程之间共享资源的好方法(以前从未尝试过超过两个)。随着python3.80的出现,多处理模块中的共享内存函数也出现了,但我还没有真正测试过,所以我不能担保 你将使用管道函数

from multiprocessing import Pipe

.....

def sending(conn):
    message = 'some message'
    #perform some code
    conn.send(message)
    conn.close()

receiver, sender = Pipe()
p = Process(target=sending, args=(sender,))
p.start()
print receiver.recv()   # prints "some message"
p.join()

有了这一点,您应该能够让独立的进程独立运行,并且当您到达需要来自一个进程的输入的点时。如果由于另一个进程的未释放数据而出现错误,您可以将其置于某种休眠或暂停状态,或者使用while循环在其他进程完成该任务并将其发送过来时持续检查挂起状态

^{pr2}$

这将使它处于无限循环中,直到另一个进程运行完毕并发送结果。这也比Queue快2-3倍。虽然排队对我个人来说也是个不错的选择,但我不使用它。在

相关问题 更多 >