这是一个关于这个答案的问题:https://stackoverflow.com/a/14241095/2332808(会评论它,但新创建的帐户显然不能,抱歉噪音。关于servlet/多线程的资源很难找到…)
建议按如下方式使用epoll:
-
epoll_ctl()
激活通知(如果使用EPOLLONESHOT
则重新激活)。 - 系统输入:
read()
/recv()
/accept()
在一个循环中直到错误EAGAIN
. -
epoll_wait()
接收通知。
但是,假设在相同的epollfd上有多个epoll_wait()
线程,如果在您完成读取之前接收到更多数据,那么在相同的fd上有另一个线程被唤醒的风险(例如,最终有两个线程处理相同的fd)
即使你把事情转过来,read()
直到EAGAIN
, epoll_ctl()
,然后再次调用read()
来检查仍然没有什么(为了避免竞争,你会在最后一次读取和epoll_ctl()
之间收到一些东西)…
但是仍然不能保证你不会在epoll_ctl()
之后实际收到一些东西,并且会有最后的read()
检查和另一个线程再次唤醒在同一fd上工作…
我想有一个锁每fd将是一个可接受的解决方案,但这是"批准"使用epoll在边缘触发模式与多个线程轮询相同的epollfd ?
是的,您仍然需要使用适当的锁来防止您所描述的那些情况-并且使用每个fd锁是最明智的方法。