虚假epoll(边缘触发)通知

时间:2014-08-20 17:06:22

标签: multithreading epoll

我对epoll和边缘触发行为的理解是,当给定文件描述符发生状态更改时,会通知您。即,当数据在fd上可用时,您会收到通知,但只有在您排空所有数据(获得EAGAIN)并且数据再次出现后才会再次收到通知。

基于这种理解,我实现了一个执行以下操作的服务器:

  1. 侦听客户端连接
  2. 对于每个连接,将fd添加到epoll
  3. 当fd上有数据时,会产生一个单独的线程,直到EAGAIN
  4. 为止
  5. 重复直到数据读取完成
  6. 半伪代码:

    n = epoll_wait(efd, events, MAXEVENTS, -1);
    
    for (i = 0; i < n; ++i) {
        check for errors;
        if (server_sock == events[i].data.fd) {
            conn = accept( ... );
            make_nonblocking(conn);
            event.data.fd = conn;
            event.events = EPOLLIN | EPOLLRDHUP;
            epoll_ctl(efd, EPOLL_CTL_ADD, conn, &event);
        } else {
            spawn_reader(events[i].data.fd);
        }
    

    使用上面的代码,我的期望是,在阅读器线程命中EAGAIN之前,epoll不会为此fd生成另一个线程。这似乎并非如此,我会产生许多线程。

    我是否错误地使用了epoll?每次我生成读者线程时,我都不需要通过EPOLL_CTL_DEL删除fd,对吗?

1 个答案:

答案 0 :(得分:0)

是的,它的工作应该如此。 epoll允许在单个控制线程(事件驱动)中进行异步IO编程。使用线程处理fd上的读取不会将其从受监视的fds列表中删除。