以下策略似乎运作良好:
不能正常工作的是EPOLLIN在回调中使用accept()监听每个线程/进程的侦听器套接字。这会唤醒每个线程/进程,但只有一个可以成功实际接受()。这就像阻止accept()在连接进入时引起踩踏的糟糕时期。
在使用EPOLLIN的同时,有没有办法让单个线程/进程唤醒接受()?或者我应该重写使用阻塞accept(),只是使用线程隔离?
只有一个线程/进程运行accept()不是一个选项,因为我试图以一种方式管理进程,每个进程都不需要知道它是否是唯一的守护进程接受( )听取器插座。
答案 0 :(得分:2)
多个套接字在同一个proto +地址+端口上监听怎么样?这可以通过Linux SO_REUSERPORT
来完成。 https://lwn.net/Articles/542629/。我没有尝试过,但我认为它甚至可以用于epoll,因为只有一个套接字可以获得实际的事件。
caveat emptor 这是一个不可移植的Linux解决方案。 SO_REUSEPORT
也会遇到链接文章中详述的一些错误/功能。
答案 1 :(得分:2)
您需要使用EPOLLET
或EPOLLONESHOT
,以便在新连接进入时EPOLLIN
事件正好唤醒一个线程。然后处理线程需要调用{{1在循环中,直到它返回accept
(EAGAIN
)或使用EPOLLET
(epoll_ctl
)手动重置,以便处理更多连接。
通常,在使用多个线程和epoll时,您需要使用EPOLLONESHOT
或EPOLLET
。否则,当事件发生时,将唤醒多个线程来处理它并且它们可能相互干扰。充其量,他们只是浪费时间搞清楚其他一些线程正在处理事件再等待之前。在最坏的情况下,他们会陷入僵局或腐败的境地。