多线程epoll

时间:2013-01-29 14:07:10

标签: c linux multithreading sockets epoll

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

  1. 为每个线程创建一个事件循环,并添加服务器套接字的文件描述符以查找每个线程上的通知。 (这可能吗?我的意思是:是epoll线程安全吗?)
  2. 创建单个事件循环并等待通知。每当收到通知时,就会生成一个线程来处理它。
  3. 如果我使用第一种方法,是否有可能多个线程被同一事件通知?我该如何处理这种情况?

    什么是最好的方法? 谢谢。

5 个答案:

答案 0 :(得分:3)

我认为选项1更受欢迎,因为非阻塞IO的主要目的是避免create& amp;破坏线程。

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

答案 1 :(得分:1)

我还使用epoll编写了一个服务器,我考虑了你所附的相同模型。

可以使用选项1,但它可能导致"雷鸣般的群体"效果,你可以阅读nginx的源代码来找到解决方案。对于选项2,我认为最好使用线程池而不是每次都生成一个新线程。

您还可以使用以下模型:

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

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

epoll是线程安全的

希望以下代码可以帮助您

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