簡體   English   中英

在每個進程的非阻塞偵聽器中使用帶有accept()的多個線程

[英]Using multiple threads with accept() on a nonblocking listener in each process

以下策略似乎效果很好:

效果不好的是EPOLLIN使用回調中的accept()監視偵聽器套接字的每個線程/進程。 盡管只有一個線程/進程可以成功地接受(accept),但這會喚醒每個線程/進程。 就像過去阻止連接接受()導致踩踏事件的糟糕時光一樣。

有沒有辦法在仍然使用EPOLLIN的情況下僅喚醒單個線程/進程以接受accept()? 還是應該重寫以使用阻塞的accept(),而只是使用線程將其隔離?

這不是一個單一的線程/進程運行accept()的選項,因為我試圖以一種不需要每個進程都知道它是否是唯一守護進程accept()的方式將進程作為池來管理。偵聽器套接字。

多個套接字在同一個proto + address + port上偵聽怎么樣? 這可以通過Linux SO_REUSERPORT來完成。 https://lwn.net/Articles/542629/ 我沒有嘗試過,但是我認為它甚至可以與epoll一起使用,因為只有一個套接字可以接收實際事件。

警告:這是一個非便攜式的,僅限Linux的解決方案。 SO_REUSEPORT還遭受鏈接文章中詳細介紹的一些錯誤/功能。

您需要使用EPOLLETEPOLLONESHOT以便在建立新連接時恰好一個線程被EPOLLIN事件喚醒。然后,處理線程需要在循環中調用accept ,直到返回EAGAINEPOLLET )或使用epoll_ctl手動重置( EPOLLONESHOT ),以便處理更多的連接。

通常,當使用多個線程和epoll時,您想使用EPOLLETEPOLLONESHOT 否則,當事件發生時,多個線程將被喚醒以處理該事件,並且它們可能會相互干擾。 充其量,他們只是浪費時間弄清楚其他線程正在處理事件,然后再等待。 最糟糕的是,它們會死鎖或損壞東西。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM