2010-09-10 22 views
1

我有一個阻塞調用accept()。從另一個線程中,我關閉了套接字,希望它能夠解除accept()調用的阻塞,但是我不知道如何處理它。線程A進入accept(),線程B關閉套接字,線程A不會從accept()返回。Unblocking accept()

問題:什麼可能導致關閉套接字不解除接受()?

+0

所以它的工作,除非它沒有?我不明白你的第一個描述(哪個成功)與你的第二個描述(哪個失敗)不同。 – 2010-09-10 01:29:49

+0

你有多確定?我建議創建一個說明問題的小程序。 – 2010-09-10 04:07:17

+0

羅伯特,我不知道有什麼區別,但是,在一個簡單的測試程序中,它稍後會在更復雜的程序中工作,但它不會。我確實知道,雖然1)套接字已關閉,並且2)同一個套接字上的accept不會返回。所以我問是否有人知道什麼時候會發生這種情況。 – Emil 2010-09-10 19:31:59

回答

0

嘗試呼叫shutdown(),然後close()從線程B。您應該檢查這些呼叫的返回碼,因爲它們可能會幫助您找出線程A無法解鎖時發生了什麼問題。

+0

調用shutdown()並沒有幫助(並不奇怪,如果調用,它會返回WSAENOTCONN)。調用closesocket(),有或沒有調用shutdown(),都會成功。我已經驗證了正在關閉的句柄與accept()調用中掛起的句柄是一樣的。沒有運氣。 – Emil 2010-09-11 19:13:37

1

當另一個線程正在或可能正在使用它時,您絕不能在一個線程中釋放資源。你會從來沒有得到這個工作可靠。首先,你永遠不可能100%確定該線程實際上在accept中被阻止,而不是要阻止線程。所以總是會有比賽條件。

而且,當然,shutdown將不起作用,因爲套接字未連接。

有幾種方法可以解決這個問題。例如,您可以設置線程在從accept返回時檢查的標誌,然後自行建立連接。這將導致線程從accept返回,然後它將看到標誌並終止。

您也可以切換到非阻塞套接字。讓線程在超時時調用selectpoll,並檢查線程是否應當從selectpoll返回時終止。您也可以在套接字和管道上使用selectpoll。然後只需在管道上發送一個字節以解除對該線程的阻塞。 pthread_kill是另一種可能性,如pthread_cancel

不知道你的問題的細節,我的猜測是最好的解決方案是重新組合,所以你沒有一個線程,其唯一的工作是永遠等待accept。這樣,你甚至不會有你需要殺死的線程。如果你不想繼續接受連接,只需操縱事情,讓你的線程停止這樣做,但讓線程繼續做其他事情。 (你有運行的線程數量應取決於事情可以有效地做數一次,而不是事物的總數,你必須做的。)

2

一個哈克技巧疏通accept(2)是實際connect(2)到從另一個線程收聽結束。翻轉一些標誌,指示是時候停止循環,connect(2),close(2)連接插座。這樣,線程就會知道關閉套接字並關閉它。