這類似於Proper way to close a blocking UDP socket的問題。我有一個線程在C從UDP套接字讀取。讀取被阻止。我想知道是否有可能能夠退出線程,而不依賴recv()返回?例如,我可以關閉另一個線程的套接字,並安全地期望套接字讀取線程退出嗎?沒有看到任何高線投票答案,這就是爲什麼我再次問。試圖從阻止UDP套接字退出閱讀
回答
這真的取決於你在哪個系統下運行。例如,如果您在符合POSIX的系統下運行並且線程可以取消,那麼當您取消線程時,recv()調用將被中斷,因爲它是一個取消點。
如果你使用的是老式插座實現,你可以設置你的線程像SIGUSR1並希望大家都不信號處理其他任何人想它和信號,因爲的recv()將中斷的信號。如果可能的話,你最好的選擇是不要阻塞。
我不認爲關閉參與阻塞操作插座是終止操作的安全保障方式。例如,kernel.org警告黑暗:
這可能是不明智的關閉文件描述符,而他們可能會在 通過使用在同一過程中的其他線程的系統調用。由於 文件描述符可能會被重複使用,有一些模糊的競爭條件 可能會導致意想不到的副作用。
相反,你可以使用一個信號,使
recv
失敗,EINTR
(確保未啓用SA_RESTART
)。您可以將信號發送到 特定線程與pthread_kill
您可以啓用插槽上
SO_RCVTIMEO
開始的recv 調用之前
個人而言,我通常會盡量避開所有的信號污穢的,但是這是一個可行的選擇。
+1爲kernel.org警告.. – jogabonito
你有一對夫婦的該選項。信號會中斷讀取操作,所以您只需確保信號消失即可。 recv操作應該失敗,錯誤編號爲EINTR。
最簡單的方法是設置一個計時器超時一些例如之後中斷自己的過程30秒:
itimerval timer
timeval time;
time.tv_sec = 30;
time.tv_usec = 0;
timer.it_value = time;
if(setitimer(ITIMER_REAL, &timer, NULL) != 0)
printf("failed to start timer\n");
你會在指定時間後得到一個SIGALRM,這會打斷你的阻塞操作,給你重複操作或退出的機會。
,而另一個線程是不能解除分配共享資源,也可能使用它。在實踐中,你會發現你甚至無法編寫代碼來執行你的建議。
想一想。當你去打電話close
,你怎麼可能知道另一個線程實際上被阻止在recv
?如果它要調用recv
,但是接着另一個線程調用socket
並獲取剛纔關閉的描述符?現在,該線程不但不會檢測到任何錯誤,而且還會在錯誤的套接字上調用recv
!
可能有一個很好的方法來解決你的外部問題,你需要退出阻塞UDP套接字讀取的原因。也有幾個醜陋的黑客可用。基本的方法是使套接字非阻塞,而不是阻塞UDP套接字讀取,僞造阻塞讀取select
或poll
。然後你可以用幾種方法中止這個循環:
一種方法是select
超時並在select
返回時檢查'abort'標誌。
另一種方法是在管道的讀取端也是select
。發送一個字節到管道來中止select
。
如果POSIX complient系統,你可以嘗試監視你的線程: 在pthread_create與功能,使你的的recv和pthread_cond_signal會剛過,然後返回。
調用線程使pthread_cond_timedwait具有所需的超時值,並在timed_out時終止被調用的線程。
- 1. 嘗試從UDP套接字讀取時出錯
- 2. Python套接字接受塊 - 阻止應用程序退出
- 3. Tcp套接字讀取總是阻止
- 4. 讀取數據從UDP套接字
- 5. Java:阻止套接字拋出EOFException
- 6. 殺死一個被阻止的UDP套接字
- 7. udp套接字停止接收數據
- 8. Android非阻塞從套接字讀取
- 9. c#套接字阻止
- 10. 阻止從輸入TCP套接字讀取
- 11. UDP套接字
- 12. 退出閱讀erb
- 13. UDP-無法從python中讀取字節從套接字?
- 14. 停止UDP套接字服務器
- 15. 套接字UDP程序在recvfrom停止
- 16. NS-3 TCP/UDP套接字是非阻塞還是阻塞?
- 17. 從讀取連接的udp套接字返回c
- 18. Phonegap UDP套接字?
- 19. MessageBox阻止從應用程序退出
- 20. 從阻止進程中優雅退出
- 21. C - 從UDP套接字緩衝區(Linux)讀取字節
- 22. 如何終止非阻塞套接字連接嘗試?
- 23. golang - 阻止應用退出
- 24. 阻止UDP轉發
- 25. PHP套接字寫入然後讀取阻塞套接字
- 26. 套接字Winsock異步阻止同時讀寫
- 27. C#套接字阻止行爲
- 28. 阻止代理使用的套接字
- 29. 阻止套接字和選擇
- 30. Java nextLine在套接字上被阻止
取消似乎是一個有前途的想法。線程的取消點是否有任何文檔可用?我看到[鏈接](http://www.mkssoftware.com/docs/man3/pthread_cancel.3.asp)它沒有列出任何套接字相關的調用。或者'recv()'反過來使用'read()'等其他調用,例如 – jogabonito
@jogabonito如果你的系統符合posix並且使用符合posix的套接字,它將會是。 [posix取消點數](http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09_05_02) –