大神們來看看這樣架構 使用epoll有沒有問題?

前提:多線程,1個主線程,N個work線程

主線程主要是用來accept, 同時create N個epoll fd(注意在主線程中create)

然後把N個EPOLL FD 依次傳入N個work線程,每個線程對應唯一一個efd,

主線程中accept的sockfd隨機(或者輪詢...) 註冊到N個efd中的一個。

在子線程中,運行事件循環,即epoll_wait(efd,....)

這樣在主線程中的註冊的sockfd會在子線程中觸發。

這樣實現會有什麼問題么??這樣和平常的在每個線程中各自 create的epoll fd有什麼區別么?? 虛心求教

---補充---

之所以這樣做,是因為當初想,accept之後,主線程就對sockfd直接註冊到了對應的epoll fd中,而不用把sockfd放入到工作線程中的隊列中,等待工作線程去取出並註冊到efd。 這樣就省了一步。。。

陳碩說的這個問題,確實,這樣主線程還會執行epoll_ctl操作(只是ADD),而同時工作線程也會對同一efd執行epoll_ctl,epoll_wait操作,,這樣「對efd的跨線程並發操作。」 具體會帶來哪些問題呢??


問題不在於你主線程epoll_create而工作線程epoll_wait,

問題在於你的工作線程中epoll_wait的時候主線程去epoll_ctl,這是對efd的跨線程並發操作。

不是說這樣一定不行,而是為什麼你不把epoll_ctl也交給工作線程去處理呢?這樣肯定不會有問題。


這樣沒問題,對epfd的操作無須另加互斥保護。但這樣的用意是什麼呢?其實epoll線程一個足夠了,epoll返回的事件分發到多個線程分別處理才是提高性能的關鍵。listenfd和普通傳入連接fd的epollin事件同樣處理即可,區別僅僅是一個調用accept一個調用read/recv


多線程還要考慮互斥,改成多進程也可以的


可以參考nginx的實現,多個進程(好像是CPU核數)同時監聽,誰搶到了就加入到自己的epoll中


每個工作線程創建的epoll實例,主線程只去做accept,這個操作可以用block方式,拿到的新連接fd分發到工作線程,接收到這個fd的worker線程,就可以在自己線程內做epoll_wait+epoll_ctl。不再需要主線的參與了。


建議去stackoverflow上問。。上面有類似問題的解答。。


既然用epoll, 那還搞這麼多線程幹嘛?


推薦閱讀:

Linux 3.x 中epoll的驚群問題?
node.js 底層使用的是epoll這種單線程io多路復用,還是多線程阻塞模型?

TAG:計算機網路 | epoll | 伺服器架構 |