2012-04-06 110 views
9

假設我在包含一堆讀文件描述符的FD_SET上調用select()。如果在select()調用期間發生文件描述符關閉,會發生什麼情況?假設發生了某種錯誤,那麼是否有責任從集合中查找並移除關閉的文件描述符?Unix:在調用select()時關閉讀文件描述符會發生什麼()

+0

請記住,當您在select()調用中時,駐留在fd_set中的filedescriptor的唯一可能方式可以關閉,如果另一個線程關閉()該描述符。 (有一個tcp連接被peer或你本地的tcp/ip棧關閉是另一回事)。 – nos 2012-04-06 16:46:18

+0

另請參閱http://stackoverflow.com/questions/3884110/what-is-select-supposed-to-do-if-you-close-a-monitored-fd – 2012-04-06 18:13:36

回答

4

我不相信這是指定的任何地方;一些系統可能立即從select返回,而其他系統可能會繼續阻止。請注意,這種情況發生的唯一方式是在多線程過程中(否則,closeselect期間不會發生;即使它發生自信號處理程序,select也會被信號中斷)。因此,這種情況可能表明你有更大的問題需要擔心。如果您正在輪詢的文件描述符中的一個可以在select期間關閉,則更大的問題是相同的文件描述符可能會被重新分配給緊接在close之後的新打開的文件(例如,在另一個不相關的線程中打開的文件)那麼輪詢可能會錯誤地在「屬於」另一個線程的新文件上執行IO。

如果你有一個由一組將與select在多線程程序輪詢的文件描述符的數據對象,你幾乎肯定需要使用某種形式的同步原語來控制訪問該組,並加入或刪除文件描述符應該需要一個與select(或成員上的任何IO)正在進行的可能性互斥的鎖。

當然,在多線程程序中,最好不要使用select,而是讓多個線程中的IO阻塞,而不用複雜的鎖定邏輯來實現所需的結果。

1

select()系統調用需要三個fd_set參數:發送,接收,異常。要檢查,如果讀取文件描述符發生錯誤,請將其包含在讀取(接收)和錯誤(exceprion)集合中 - 在從select()返回的異常集中查看它意味着該套接字發生異常,你有機會找出什麼。

一般來說,任何異常的網絡套接字將不再適合發送和接收。

+0

實際上'exceptfds'用於緊急數據。 – cnicutar 2012-04-06 16:30:09

+0

http://linux.die.net/man/2/select以及我的經驗否則:*「這些[文件描述符]在exceptfds將被監視的例外」* – 2012-04-06 16:34:04

+0

我不喜歡宣傳我的答案,但我確實添加了一個鏈接和一個報價。 – cnicutar 2012-04-06 16:34:48

1

即使您已經讀取了所有發送的數據,封閉的套接字始終被視爲可以讀取。選擇將解除阻塞,表明套接字可用。