2014-01-06 42 views
1

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

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需要ints(文件描述符)或带有无参数函数fileno()的对象(使用Pipe()创建的Connection对象已获得)。我甚至试过:

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

但错误是一样的。任何ideads?

编辑

是的,我目前在Windows上工作,但它看起来像我将不得不改变平台...感谢您的答案。我有这种想法,在Windows上这些文件描述符可能无法正常工作,但我不确定。现在我明白了。谢谢!

回答

2

您打电话给select(),其中包含Connection对象,如multiprocessing所用。 (顺便说一句,你在写你的源代码multiprocess,但我想它应该是multiprocessing。)然而,select()不能处理这些。

请尝试使用pipe1.fileno()等。这是一个文件编号(一个int),select可以完美地处理这些文件。

编辑:

如果您使用的是Windows工作,文件编号不被select()(倒霉)的支持。我无法帮助。除非你愿意去多线程,并且有一个线程可以等待每一个东西;这也应该在Windows上工作。

2

你在Windows上运行吗?

The docs say

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

老实说,我不知道什么是轮询/从标准库中选择在Windows上工作。可能Python for Windows Extensions提供了一个不错的WaitForMultipleObjects包装。

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]) 

“可读”和“可写入”随后将列出可读取或可写入的管道。你可以扩展这个函数,让它做更多你想要的东西,或者只是迭代函数。