2014-01-06 46 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]) 

「可讀」和「可寫入」隨後將列出可讀取或可寫入的管道。你可以擴展這個函數,讓它做更多你想要的東西,或者只是迭代函數。