12

我正在使用 epoll(边缘触发)和非阻塞套接字创建一个多线程服务器。目前我正在主线程上创建一个事件循环并等待通知并且它工作正常
我必须在两种方法之间进行选择以使其成为多线程:

  1. 为每个线程创建一个事件循环并添加服务器套接字的文件描述符以查找每个线程上的通知。(这可能吗?我的意思是:epoll 线程安全吗?)
  2. 创建单个事件循环并等待通知。每当收到通知时,都会产生一个线程来处理它。

如果我使用第一种方法,是否有机会让多个线程收到相同事件的通知?我该如何处理这种情况?

什么可能是最好的方法?谢谢你。

4

5 回答 5

5

我认为选项 1 更受欢迎,因为非阻塞 IO 的主要目的是避免创建和销毁线程的开销。

以流行的 web 服务器 nginx 为例,它创建多个进程(不是线程)来处理一个句柄上的传入事件,并在子进程中处理事件。它们都共享同一个监听套接字。它与选项 1 非常相似。

于 2013-01-29T14:25:58.863 回答
1

我也在使用 编写服务器epoll,并且我考虑了与您附加的相同模型。

使用选项1是可以的,但是可能会造成“雷声从众”的效果,可以阅读nginx的源码找到解决方法。至于选项2,我认为最好使用线程池而不是每次都产生一个新线程。

并且您还可以使用以下型号:</p>

主线程/进程:accept使用阻塞 IO 的传入连接,并使用 BlockingList 将 fd 发送到其他线程或使用PIPE.

子线程/进程:分别创建一个实例epoll,并将传入的 fd 添加到 中epoll,然后用非阻塞 IO 处理它们。

于 2015-08-20T09:12:26.630 回答
0

epoll 是线程安全的,一个好的解决方案是你的主进程留在 accept(2) 中,一旦你在目标线程的 epoll fd 中获得文件描述符寄存器,这意味着每个线程都有一个 epoll 队列,创建线程后,您将共享 epoll 文件描述符作为调用 pthread_create(3) 中的参数,因此当新连接到达时,您将 epoll_ctl(...EPOLL_CTL_ADD..) 使用目标线程的 epoll fd 和在接受(2)之后创建的新套接字有意义吗?

于 2013-02-14T19:19:10.400 回答
0

每个线程的事件循环是最灵活的高性能你应该为每个事件循环创建一个epoll fd,不用担心epoll线程安全问题。

于 2014-01-22T03:27:16.817 回答
0

epoll 是线程安全的

希望下面的代码可以帮助你

https://github.com/jingchunzhang/56vfs/blob/master/network/vfs_so_r.c

于 2015-06-18T06:36:52.437 回答