我在ucLinux上爲套接字通信編寫代碼。我使用select()
來讀取套接字上的數據。我也有一個20毫秒的定時器(使用setitimer
創建)運行在同一線程中執行並行操作。每次選擇「被系統調用中斷」時,我的選擇函數都會被阻塞,因爲它每20毫秒就會收到定時器在溢出時發出的SIGALRM信號問題。 EINTR發佈後,我嘗試重新啓動系統,然後再次運行select()
。但這不會有幫助,因爲我會每隔20毫秒就會收到定時器的SIGALRM。我不想忽略這個信號,因爲它用於執行系統中的其他任務,但是我想使用select而不受此信號的影響。有什麼辦法可以解決這個問題嗎?我無法使用像timer_create()
這樣的功能,因爲這些功能在我使用的平臺上不受支持。所以,我堅持使用setitimer
來創建定時器。有什麼辦法可以在我的代碼中獨立運行嗎?在同一個linux線程中運行select()套接字和定時器
回答
是否有這樣的選擇?
While(1) {
int rc = select(nfds, &readfds, &writefds, &exceptfds, &timeout);
if ((rc < 0) && (errno == EINTR))
continue;
else {
// some instructions
}
}
如果這是不是你指定一組應在PSELECT()期間不被阻止信號的選項,您也許可以使用PSELECT增加了一個參數來結束(sigmask),見here
你在做什麼很奇怪。讓我們面對現實吧:定時器是一個古老的,大多數已經過時的工作機制。現在幾乎每個人都避免像鼠疫這樣的信號。在信號回調中基本上沒什麼用處(你當然不能像malloc
那樣調用任何複雜的東西),所以你必須有一些方法讓計時器通知從SIGALRM
處理程序返回到主線程 - 你實際上做信號處理器的工作是你嗎?
所以你有兩種策略:使用標準的自管式技巧將信號轉化爲fd上的事件,這是處理諸如SIGTERM
,SIGINT
等事件的「常規」方式。您可以撥打socketpair
或pipe
來製作管道,然後從信號處理程序中向管道中寫入一個字節。你從你的select
循環讀回字節。你通常把信號的值寫成數據,但你可以真的寫任何東西。
另一種策略(更理智)是完全避免信號和setitimer
的混亂。 setitimer
是嚴重的遺留問題,並導致各種問題(例如,它可能導致像getaddrinfo
這樣的函數掛起,glibc中仍然沒有修復的錯誤(http://www.cygwin.org/frysk/bugzilla/show_bug.cgi?id=15819)。信號對您的健康有害。因此,「normal 「策略是使用超時參數select
您有一個定時器的鏈表,用於管理代碼中定期事件的對象。當您撥打select
時,將使用剩餘定時器中最短的時間作爲超時值。當select
調用返回,你檢查是否有定時器過期,並調用定時器處理程序以及你的fd事件處理程序,這是一個標準的應用程序事件循環,這樣你的循環代碼就可以監聽定時器驅動的事件以及fd驅動事件幾乎系統上的每個應用程序都在此機制上使用某種變體
- 1. Linux套接字和多線程程序
- 2. 一個偵聽套接字必須在線程中運行嗎?
- 3. 在套接字編程的select()中重新啓動定時器
- 4. 運行時unix套接字應該在Linux上運行?
- 5. 一個寫線程,一個讀線程在同一個套接字上?
- 6. 在python中同時運行多個套接字
- 7. 當有多個套接字時,Linux OS如何調度線程
- 8. Linux套接字終止偵聽線程
- 9. 定時器運行在與創建它不同的線程中
- 10. 在一個線程中創建兩個套接字連接
- 11. 是否可以在同一臺機器上運行套接字服務器和套接字客戶端?
- 12. 套接字和線程
- 13. 套接字和多線程
- 14. 套接字線程和PyGTK
- 15. 線程和套接字
- 16. 流式套接字服務器在Linux中無法處理超過382個線程(每個連接一個)
- 17. Linux中的套接字,線程和文件描述符
- 18. Linux select()和多個套接字的FIFO排序?
- 19. linux - 運行一個進程並同時拖拽一個文件
- 20. 只有一個線程在執行器服務中同時運行,RabbitMQ
- 21. Linux UDP套接字:select()沒有通知?
- 22. 雙UDP套接字在兩個不同的UDP套接字在Linux中
- 23. EventMachine:在主線程中運行定時器和回調嗎?
- 24. 多個線程到同一個TCP套接字
- 25. 在同一個應用程序中同時運行AQXMLParser和NSXMLParser
- 26. Java:多個套接字在一個線程中發送和接收維護
- 27. 在同一系統上運行時,套接字服務器/客戶端衝突
- 28. 線程服務器套接字在python
- 29. 如何在同一端口上運行套接字和websocket服務器?
- 30. 在C++ Linux中的套接字超時
嗨, 感謝您的建議。我已經這樣做了。但問題是它在select中保持循環,因爲它在每20毫秒(即定時器在同一線程上運行的時間)之後始終由系統獲取EINTR。因此,我有一個選擇函數可以繼續運行,中斷並且再次運行,並且最終最終在套接字上讀取任何內容,只是保持循環發出中斷的呼叫信號。 有什麼辦法可以避免這種情況?我需要定時器在同一個線程中,我不能忽略定時器信號,也不能阻止選擇功能。任何方式實現兩者? – user2069669
@ user2069669增加了對pselect的引用,你可以使用而不是select – Jekyll