2009-06-26 57 views
5

我正在從多個串行端口讀取數據。目前我正在使用自定義信號處理程序(通過設置sa_handler)根據文件描述符信息來比較和喚醒線程。我正在尋找一種解決方案,讓單個線程擁有獨特的信號處理程序,在這方面,我發現要使用選擇系統調用。在線程中選擇()系統調用?

現在我以下的問題:

  1. 如果我使用一個線程(QT),那麼我應該把選擇的系統調用監控的串行端口?
  2. 選擇系統調用線程安全嗎?
  3. 它是CPU密集型的,因爲我的應用程序中發生了很多事情,包括GUI更新?

請不要介意,如果您發現這些問題很荒謬。我從來沒有使用過這樣的串行通信機制。

回答

7

POSIX specification (select)是尋找select定義的地方。我個人推薦poll - 它有一個更好的接口,可以處理任意數量的描述符,而不是系統定義的限制。

如果我理解正確,你是基於某些描述符的狀態喚醒線程。更好的方法是讓每個線程都有自己的描述符和呼叫選擇自己。你看,選擇不會修改系統狀態,並且只要你使用線程局部變量,它將是安全的。但是,您一定要確保不要關閉線程所依賴的描述符。

使用select/poll超時會讓「等待」直到內核端,這意味着線程通常會進入睡眠狀態。當線程正在休眠時,它不使用任何CPU時間。另一方面,在沒有超時的情況下,select呼叫上的while/for循環將使您的CPU使用率更高,因爲您一直在循​​環中旋轉。

希望這會有所幫助。

編輯:另外,在多線程相同描述工作時select/poll可以有不可預知的結果。原因很簡單,第一個線程可能會被喚醒,因爲描述符已準備好讀取,但第二個線程必須等待下一個「可用於讀取」喚醒。

只要你不是select在多個線程相同的描述符,你應該沒有問題。

+0

Gud info!一個問題。線程如何知道它需要喚醒,如果套接字fd準備好進行讀/寫操作。內核是否給線程一些中斷? – 2013-05-19 18:20:20

0

這是一個系統調用 - 它應該是線程安全的,我認爲。

我以前沒有這樣做過,但我會感到很驚訝,如果它不在那裏。 CPU密集度如何,在很大程度上取決於您正在等待的文件句柄的數量。主要使用select()來等待一個(> 1個)文件句柄準備就緒。

還應該提到的是,select()不應該用於輪詢文件句柄 - 出於性能原因。正常的用法是:你的工作已經完成,並且有一段時間可以流逝直到下一件事發生。現在,您暫停您的選擇並讓其他進程運行。 select()通常會暫停活動進程。如何與線程一起工作,我不確定!我認爲,整個過程(以及所有線程)都被暫停。但這可能是有記錄的。它也可以取決於(在Linux上)是否使用系統線程或用戶線程。內核不會知道用戶線程並因此暫停整個過程。

+0

這真的不是一個好答案。很多猜測工作...什麼是「用戶線程」呢?! – 2018-03-03 02:28:41