文档建议
先说epoll 官方文档的建议,在ET模式下,如果用多线程epoll_wait 同一个epoll-fd,那么当其监听fd产生了事件,此时理论上所有的线程都会收到通知,这将导致群惊,因此epoll只会唤醒一个线程来处理!
但是,此时如果fd又触发了新的事件,那么就会唤醒新的线程!这将会导致多个线程操作同一个fd,这不是推荐的方式,可能导致线程安全问题!
解决方案是使用EPOLLNESHOT标志,即在一次wait返回后禁止fd再产生事件,并在处理完成后使用epoll_ctl的MOD操作重新开启。
webServer 实践
但是在webServer的实现里面,一般是这样的:
一个线程负责监听TCP链接,当收到用户的TCP链接后,创建client-fd ,然后从线程池中挑选一个线程,将client -fd添加到工作线程的epoll中,当client-fd收到HTTP请求,由工作线程处理之。
换句话说,每个线程都处理自己的fd,从而完全避免多线程安全问题,当然了上述操作主要是为了高并发,它有个熟悉的名字,Reactor模型。
Pistache就是上述工作模式。
网友评论