我正在使用多線程嵌入式應用程序,其中epoll在其中一個線程中用於IO。我依賴epoll的一個特殊功能,它指定關閉一個文件描述符會自動將它從epoll集中移除(man 7 epoll中的Question/Answer 6)。在這種情況下,文件描述符關閉在調用epoll_wait
的同一個線程中完成。結果發生的是epoll_wait
在關閉文件描述符後返回一個事件,並且程序最終崩潰,因爲它試圖訪問當文件描述符關閉時解除分配的資源。據我所知,文件描述符在任何地方都沒有,儘管我不知道如何驗證它。我知道有一個事實,即沒有撥打fork()
,dup()
,dup2()
或fcntl()
與特定的dup選項。這個特定的文件描述符是用EPOLLOUT
,EPOLLIN
,EPOLLERR
和EPOLLHUP
登記的。它是電平觸發的。有沒有人知道這個功能的任何警告?手冊頁是否有誤?任何有用的信息可以幫助我進一步調試該問題?我知道我可以從集合中刪除文件描述符,但我想知道爲什麼會發生這種情況。Epoll_wait在關閉的文件描述符上返回事件
回答
關閉一個文件描述符似乎並沒有將它從epoll中移除。我在3.12.2上用一個非常簡單的例子試了一下。我傾向於將該手冊頁稱爲錯誤或不準確。
我在測試做了什麼:
- 創建TCP套接字
- 束縛,爲localhost:5555
- 設置它來聽
- 創建了一個epoll的
- 添加的插座有hup,err和
- 睡了一下,所以我可以選擇使用nc連接
- 關閉套接字
- epoll_wait
- epoll_ctl德爾
- 清理
等待工作,即使插座已被關閉我是否已經連接到這一點。
編輯:The epoll_ctl_del
如果套接字已關閉,則確實失敗。在閱讀了當前的手冊頁之後,看起來他們確實沒問題。 epoll頁面指向選擇(2)關於關閉被監視的套接字,並且該頁面表示行爲未指定。
爲了記錄,我在一個服務器上做了什麼,當一個連接被關閉時,我明確地將它從epoll中刪除(並且實際上標記了epoll以重新等待它剛剛從epoll_wait中出來,這是運行在另一個線程),然後繼續關閉並銷燬相關資源。 –
epoll_ctl del在你的例子中工作的事實是高度可疑的。套接字未關閉或者已被複制。我們可以看到代碼嗎? –
找到了代碼。果然,'epoll_ctl_del'確實失敗了。我爲我的測試程序製作了「doclose」標誌,以檢查epoll等待返回值是否在關閉套接字的情況下進行,並且我必須在沒有關閉的情況下從運行中獲取「del工作」,當然它的工作原理。 –
- 1. 關閉文件描述符
- 2. 關閉文件描述符是怎麼回事?
- 3. python關閉文件描述符問題
- 4. Python沒有關閉文件描述符
- 5. 文件描述符返回錯誤值
- 6. 文件描述符,打開()返回零
- 7. 關閉原始文件描述符後,重複的描述符文件是否關閉?
- 8. 文件描述符未在exec上關閉
- 9. 替代epoll_wait,它不等待文件描述符?
- 10. 複製文件失敗,EBADF關閉輸出文件描述符
- 11. 關閉文件指針而不關閉底層文件描述符
- 12. 在子進程中關閉已打開的文件描述符
- 13. 關閉正在輪詢的文件描述符
- 14. 無法打開文件,文件描述符返回-1值
- 15. 如何在python中關閉文件描述符?
- 16. 在C中關閉管道,dup2,文件描述符?
- 17. 這些文件描述符關閉的目的是什麼?
- 18. 什麼是關閉一個無效的文件描述符呢?
- 19. 錯誤的文件描述符關閉Boost套接字
- 20. 的Python:關閉文件描述符daemonizing過程
- 21. 文件描述符飢餓和阻斷文件描述符
- 22. 文件描述符和進程關係
- 23. 關閉了一個名爲文件描述符
- 24. 關閉文件描述符,然後使用它
- 25. Linux內核 - 套接字文件描述符關閉位置
- 26. 如何通過Linux shell命令關閉文件描述符
- 27. 父/子進程關閉文件描述符
- 28. 關閉log4j記錄器以釋放文件描述符
- 29. pthread_detach上的錯誤文件描述符
- 30. ftell上的文件描述符?
epoll_wait爲該文件描述符返回的事件是EPOLLIN,EPOLLHUP和EPOLLERR。 – duffsterlp
您可以使用[strace](http://linux.die.net/man/1/strace)來驗證您的程序是否在執行您認爲正在執行的操作。你能在一個簡單的單線程測試程序中重現這種行爲嗎? –