2013-10-08 32 views
2

我使用select()調用無限制地讀取數據的專用線程中的串行端口fd上。我找不到一種方法從我選擇的呼叫中醒來(除非我設置了超時等)。在套接字編程中,你有shutdown()調用來喚醒在select()上被阻塞的線程。在Linux中喚醒阻止串口讀取

儘管有串口,但我沒有看到任何模擬。在select()阻塞我的'reader'線程時,從另一個線程調用close()在POSIX上看起來並沒有很好的定義。特別是在Linux上,在fd上調用close()不會喚醒在該fd上調用select()的任何線程。從(http://linux.die.net/man/2/select):

如果select()監視的文件描述符在另一個線程中關閉,則結果是未指定的。在某些UNIX系統上,select()取消阻塞並返回,並指示文件描述符已準備就緒(隨後的I/O操作可能會失敗並顯示錯誤,除非另一個文件描述符在select()返回的時間和I/O操作已執行)。在Linux(和其他一些系統)上,在另一個線程中關閉文件描述符對select()沒有影響。總而言之,在這種情況下依賴於特定行爲的任何應用程序必須被視爲buggy。

是否有可能喚醒在Linux的串口fd上無限期阻塞的線程,如果是這樣,怎麼辦?

編輯:

有一個「hack'十歲上下的方式,通過與睡眠(循環調用select())來解決這個問題(這是不理想的,雖然,因爲現在有一個喚醒請求之間的延遲和線程實際上醒來)。在循環系統中調用select有什麼不利嗎?

+0

只要事件發生在任何集合中的任何描述符上,'Select'調用就會被喚醒。也許你需要把描述符放入特殊設置中? –

+0

因爲現在我只會在閱讀fds中嘗試,但是基於desc。在我更新的答案,它似乎不會是可靠的 – Prismatic

+0

編輯 - 即使fd被添加到例外設置,也沒有任何反應。 – Prismatic

回答

0

兩個典型的解決方案:

  1. 創建管道並將其添加到選擇的隊列。只要您通過此管道發送數據 - 請選擇退出。

  2. 如果喚醒所有線程不是問題,您可以發送信號。