选择多个管道

时间:2014-01-06 15:07:25

标签: python python-3.x multiprocessing pipe

我有多个管道对象(双向)。我需要的是等到任何这些管道出现任何物体。不幸的是,当我尝试做这样的事情时:

from multiprocess import Pipe
import select

class MyClass:
    def __init__(self, pipe1, pipe2):
        self.__my_pipes = [pipe1, pipe2]

    def run(self):
        while 1:
            ready, _, _ = select.select(self.__my_pipes, [], [])
            #and some stuff

我收到错误

OSError: [WinError 10038] an operation was attempted on something that is not a socket

MyClass的构造函数调用如下:

pipe1, pipe2 = Pipe()
pipe3, pipe4 = Pipe()
obj = MyClass(pipe1, pipe3)

根据文档,select.select需要int(文件描述符)或具有无参数函数fileno()的对象(使用Pipe()创建的Connection对象)。我甚至试图这样做:

w, r = os.pipe()
read, _, _ = select.select([w, r], [], [])

但错误是一样的。任何想法?

修改

是的,目前我正在使用Windows,但看起来我不得不改变平台......感谢您的回答。我有这样的想法,在Windows上那些文件descirptors可能无法正常工作,但我不确定。现在我知道了。谢谢!

3 个答案:

答案 0 :(得分:2)

您正在使用select()使用的包含Connection个对象的数组调用multiprocessing。 (顺便说一句,你在源代码中写了multiprocess,但我想它应该是multiprocessing。)select()但是,无法处理这些。

请尝试使用pipe1.fileno()等;这是一个文件号(一个int),select完全能够使用它们。

编辑:

如果您正在使用Windows,select()不支持文件编号(运气不好)。我忍不住了。除非你愿意去多线程并且每个东西都有一个线程要等待;这也适用于Windows。

答案 1 :(得分:2)

你在Windows上运行吗?

The docs say

  

Windows上的文件对象是不可接受的,但是套接字是。在Windows上,底层的select()函数由WinSock库提供,不处理不是源自WinSock的文件描述符。

老实说,我对在Windows上运行的标准库进行轮询/选择一无所知。可能Python for Windows Extensions提供了一个不错的WaitForMultipleObjects包装器。

答案 2 :(得分:0)

可以使用管道自己的函数轮询,或者它的变量是可读的,可写的

pipe1.poll()
pipe1.writable
pipe1.readable

它不一样,但像这样的代码可以做你想要的:

def return_pipes(pipes):
    readable = []
    writable = []
    for pipe in pipes:
        if pipe.readable:
            readable.append(pipe)
        if pipe.writable:
            writable.append(pipe)
    return(readable,writable)

readable,writable = return_pipes([pipe1,pipe2])
然后,“可读”和“可写”将是具有可读或可写管道的列表。您可以扩展该功能,使其更多地执行您想要的功能,或者只是迭代功能。