我有多个管道对象(双向)。我需要的是等到任何这些管道出现任何物体。不幸的是,当我尝试做这样的事情时:
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可能无法正常工作,但我不确定。现在我知道了。谢谢!
答案 0 :(得分:2)
您正在使用select()
使用的包含Connection
个对象的数组调用multiprocessing
。 (顺便说一句,你在源代码中写了multiprocess
,但我想它应该是multiprocessing
。)select()
但是,无法处理这些。
请尝试使用pipe1.fileno()
等;这是一个文件号(一个int),select完全能够使用它们。
编辑:
如果您正在使用Windows,select()
不支持文件编号(运气不好)。我忍不住了。除非你愿意去多线程并且每个东西都有一个线程要等待;这也适用于Windows。
答案 1 :(得分:2)
你在Windows上运行吗?
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])
然后,“可读”和“可写”将是具有可读或可写管道的列表。您可以扩展该功能,使其更多地执行您想要的功能,或者只是迭代功能。