2016-02-17 24 views
0

我想從一個套接字讀取數據時可用,並在同一個線程我想讀從消息隊列中的項目是這樣的:選擇()上的插座,另一事件機制

while True: 
    ready = select.select([some_socket, some_messagequeue], [], [])[0] 
    if some_socket in ready: 
     read_and_handle_data_from_socket() 
    if some_messagequeue in ready: 
     read_and_handle_data_from_messagequeue() 

與其他詞:一旦線程通過一些進程內部消息系統接收到消息,我想中止select()

從我現在看我發現了兩個方法:select荷蘭國際集團的消息隊列本身或中止select()創建os.pipe()但我沒有找到一個很好的實現呢。

方法1:有似乎是兩個Queue實現:multiprocessing.Queuequeue.Queue(Python3)。雖然multiprocessing.Queue有一個_reader成員,可以使用select()只有queue.Queue允許排隊任意數據結構,而不必攪拌酸洗。

問題:有沒有辦法在queue.Queue上使用select()

方法2:應該是這樣的:

import os, queue, select 
r, w = os.pipe() 
some_socket = 67 # FD to some other socket 
q = queue.Queue() 
def read_fd(): 
    while True: 
     ready = select.select([r, some_socket], [], [])[0] 
     if r in ready: 
      os.read(r, 100) 
      print('handle task: ', q.get()) 
     if some_socket in ready: 
      print('socket has data') 

threading.Thread(target=read_fd, daemon=True).start() 
while True: 
    q.put('some task') 
    os.write(w, b'x') 
    print('scheduled task') 
    time.sleep(1) 

而這個工作 - 但在我眼裏這個代碼是相當麻煩,不是很Python的。 問題:有沒有更好的方式發送'信號'通過os.pipe(或任何其他實施)?

方法3..N問:你將如何解決這個問題?

我知道像ZeroMQ這樣的庫,但由於我正在開發一個嵌入式項目,我更喜歡本地Python(3.3)發行版附帶的解決方案。我認爲應該有一個解決方案與第一個例子一樣短 - 畢竟我只想中止select()如果在消息隊列上發生了什麼。

回答

0

方法3:有兩個線程。 1等待選擇。 2在消息隊列中等待。互斥體,以防止它們同時觸發。爲什麼有線程,如果你不打算使用它們?

+0

那麼,我需要消息隊列與第一個線程進行通信。我必須從第一個線程訪問資源,第二個線程_instructs_是第一個執行任務的線程。所以我真的需要一種方法讓第一個線程從消息隊列中讀取。 – frans

0

您可以創建通過書面pipe對文件描述符,信號隊列推到它的寫入結束,等待隊列活動在同一select在管道的讀端。

在Linux中,有eventfd(2)系統調用,可以爲同一目的而使用而不是pipe(2)this可能對我有用)。

+0

好吧,這正是我在'方法2'中所做的 - 我錯過了什麼嗎? – frans

+0

啊,是的,沒有仔細閱讀這個問題。將修改。 –