关闭fd 0后epoll队列中的tty事件

时间:2014-01-23 19:10:29

标签: epoll

考虑以下情况:

  • 为fd 0(stdin)
  • 注册了EPOLLIN事件
  • 为fd 0生成一个EPOLLIN事件,并在epoll
  • 中隐式排队等待读取
  • fd 0关闭(和EPOLL_CTL_DELeted) 之前调用epoll_wait()
  • 调用epoll_wait()来读取排队的事件

现在:

  • 如果stdin是终端,当调用epoll_wait()时,将报告步骤2中的EPOLLIN事件
  • 如果stdin不是终端而是管道,则步骤2中的EPOLLIN事件将报告

为什么tty案例不同?

测试程序:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/epoll.h>

struct epoll_event event1 = {
    .events = EPOLLIN,
    .data = { .fd = 0}
};

int main(int argc, char **argv)
{
    int epfd = epoll_create(1);
    int rc;
    epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &event1);
    sleep(2); //allow meself time to type false\n
    printf("closing stdin ...\n");
    close(0);
    //even if i remove it explicitly the event will be found in the que after
    epoll_ctl(epfd, EPOLL_CTL_DEL, 0, &event1);
    printf("gathering events ...\n");
    event1.events = 0;
    event1.data.fd = -1;
    rc = epoll_wait(epfd, &event1, 1, 0);
    switch(rc) {
        case 1:
            printf("event received: event=%d on fd %d\n", event1.events, event1.data.fd);
            break;
        case 0:
            printf("no events received");
            break;
        case -1:
            printf("epoll_wait error\n");
            break;
        default:
            printf("weird event count %d\n", rc);
    }

    return 0;
}

使用来自tty的stdin运行程序:

[root@tinkerbell src]# ./epolltest 
false
closing stdin ...
gathering events ...
event received: event=1 on fd 0
[root@tinkerbell src]# false
[root@tinkerbell src]# 

使用管道中的stdin运行程序:

[root@tinkerbell src]# cat t.sh
#!/bin/bash

echo "bah";
sleep 10;
[root@tinkerbell src]# ./t.sh | ./epolltest 
closing stdin ...
gathering events ...
no events received[root@tinkerbell src]# 

1 个答案:

答案 0 :(得分:0)

different question but the answer can be applied here as well

  

epoll捕获的事件来自文件*,因为它是   抽象内核处理。事件确实发生在文件*和   如果你把一个fd复制1000次,那就没办法了   事件是fd = 122。