在每个进程中的非阻塞侦听器上使用带有accept()的多个线程

时间:2013-10-21 11:37:47

标签: c multithreading sockets nonblocking

以下策略似乎运作良好:

不能正常工作的是EPOLLIN在回调中使用accept()监听每个线程/进程的侦听器套接字。这会唤醒每个线程/进程,但只有一个可以成功实际接受()。这就像阻止accept()在连接进入时引起踩踏的糟糕时期。

在使用EPOLLIN的同时,有没有办法让单个线程/进程唤醒接受()?或者我应该重写使用阻塞accept(),只是使用线程隔离?

只有一个线程/进程运行accept()不是一个选项,因为我试图以一种方式管理进程,每个进程都不需要知道它是否是唯一的守护进程接受( )听取器插座。

2 个答案:

答案 0 :(得分:2)

多个套接字在同一个proto +地址+端口上监听怎么样?这可以通过Linux SO_REUSERPORT来完成。 https://lwn.net/Articles/542629/。我没有尝试过,但我认为它甚至可以用于epoll,因为只有一个套接字可以获得实际的事件。

caveat emptor 这是一个不可移植的Linux解决方案。 SO_REUSEPORT也会遇到链接文章中详述的一些错误/功能。

答案 1 :(得分:2)

您需要使用EPOLLETEPOLLONESHOT,以便在新连接进入时EPOLLIN事件正好唤醒一个线程。然后处理线程需要调用{{1在循环中,直到它返回acceptEAGAIN)或使用EPOLLETepoll_ctl)手动重置,以便处理更多连接。

通常,在使用多个线程和epoll时,您需要使用EPOLLONESHOTEPOLLET。否则,当事件发生时,将唤醒多个线程来处理它并且它们可能相互干扰。充其量,他们只是浪费时间搞清楚其他一些线程正在处理事件再等待之前。在最坏的情况下,他们会陷入僵局或腐败的境地。