我正在创建一个使用epoll (边缘触发)和非阻塞套接字的多线程服务器。目前,我正在主线程上创建一个事件循环,并等待通知,它可以正常工作
我必须在两种方法中进行选择,以使其成为多线程:
如果我使用第一种方法,是否有机会让多个线程收到相同事件的通知?我该如何处理这种情况?
最好的方法是什么?谢谢。
发布于 2013-01-29 22:25:59
我认为选项1更受欢迎,因为非阻塞IO的主要目的是避免创建和销毁线程的开销。
以流行的web服务器nginx为例,它创建多个进程(而不是线程)来处理句柄上的传入事件,而进程处理子进程中的事件。它们都共享相同的侦听套接字。它与选项1非常相似。
发布于 2015-08-20 17:12:27
我也在使用epoll
编写一个服务器,我已经考虑了与您附加的相同的模型。
可以使用选项1,但它可能会造成“雷鸣羊群”效应,您可以阅读nginx的源代码来找到解决方案。至于选项2,我认为使用线程池比每次产生一个新线程更好。
您还可以使用以下模型:
主线程/进程:使用阻塞IO的accept
传入连接,并使用BlockingList将fd发送到其他线程或使用PIPE
将fd发送到其他进程。
子线程/进程:分别创建epoll
实例,并将传入的fd添加到epoll
中,然后使用非阻塞IO进行处理。
发布于 2013-02-15 03:19:10
epoll是线程安全的,一个好的解决方案是你的主进程停留在accept(2)中,一旦你得到了文件描述符为目标线程在epoll中注册了一个,这意味着你为每个线程都有一个epoll队列,一旦你创建了线程,你就在调用pthread_create(3)中共享了epoll文件描述符作为参数,所以当一个新的连接到达时,你做一个epoll_ctl(...EPOLL_CTL_ADD..)将epoll fd用于目标线程和在accept(2)之后创建的新套接字,有意义吗?
https://stackoverflow.com/questions/14584833
复制相似问题