是否必须通过继承将multiprocessing.Pipe传递给子进程

时间:2016-01-16 23:03:46

标签: python pipe multiprocessing python-multiprocessing

我理解multiprocessing.Queue has to be passed to subprocess through inheritance。但是,当我尝试通过消息传递将Pipe传递给子进程时,就像下面的代码一样,我得到的错误并不是说“管道只能通过继承在进程之间共享”。相反,它在q.get()失败,错误显示为TypeError: Required argument 'handle' (pos 1) not found。我想知道它是否有可能这样做?假设管道是使用linux命名管道实现的,那么重要的是管道的名称,它可能是序列化并在进程之间传递的状态吗?

from multiprocessing import Process, Pipe, Queue    

def reader(q):
  output_p = q.get()
  msg = output_p.recv()
  while msg is not None:
    msg = output_p.recv()    

if __name__ == '__main__':
    q = Queue()
    reader_p = Process(target=reader, args=(q,))
    reader_p.start()     # Launch the reader process

    output_p, input_p = Pipe(True)
    q.put(output_p)

    input_p.send('MyMessage')
    input_p.send(None)
    reader_p.join()

2 个答案:

答案 0 :(得分:0)

这是一个bug,已在Python 3中修复。

你在Python 3中的代码完美无缺。

答案 1 :(得分:0)

noxadofox在这里给出了正确的答案。我要添加一个示例,该示例旨在验证管道不需要继承。在此示例中,我在执行程序启动其两个进程之后创建第二个管道,并将其作为参数传递给现有进程。

""" Multiprocessing pipe and queue test """
import multiprocessing
import concurrent.futures
import time


class Example:
    def __init__(self):
        manager = multiprocessing.Manager()
        q = manager.Queue()
        executor = concurrent.futures.ProcessPoolExecutor(max_workers=2)

        pipe_out_1, pipe_in_1 = multiprocessing.Pipe(duplex=True)
        executor.submit(self.requester, q, pipe_in_1)
        executor.submit(self.worker, q, pipe_out_1)
        print(executor._processes)

        pipe_out_2, pipe_in_2 = multiprocessing.Pipe(duplex=True)
        executor.submit(self.requester, q, pipe_in_2)
        executor.submit(self.worker, q, pipe_out_2)
        print(executor._processes)

    @staticmethod
    def worker(q, pipe_out):
        task = q.get()
        print('worker got task {}'.format(task))
        pipe_out.send(task + '-RESPONSE')
        print('loop_proc sent')

    @staticmethod
    def requester(q, pipe_in):
        q.put('TASK')
        response = pipe_in.recv()
        print('requester got response {}'.format(response))
        time.sleep(2)


if __name__ == '__main__':
    Example()
    time.sleep(30)