2012-10-26 80 views
2

我看到两个不同的二进制文件不同epollselect行为,并希望一些调试帮助。在下文中,epoll_waitselect将互换使用。无法从epoll_wait醒来时,其他进程关闭FIFO

我有两个过程,一个作家和一个读者,在FIFO通信。读者执行epoll_wait以获得写入通知。我也想知道,当作家关闭FIFO,并且看起来epoll_wait应该通知我这一点。下列玩具程序,其行为与预期相同,说明了什么,我试图完成:

#include <errno.h> 
#include <fcntl.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/epoll.h> 
#include <sys/stat.h> 
#include <unistd.h> 

int 
main(int argc, char** argv) 
{ 
    const char* filename = "tempfile"; 
    char buf[1024]; 
    memset(buf, 0, sizeof(buf)); 

    struct stat statbuf; 
    if (!stat(filename, &statbuf)) 
    unlink(filename); 

    mkfifo(filename, S_IRUSR | S_IWUSR); 

    pid_t pid = fork(); 
    if (!pid) { 
    int fd = open(filename, O_WRONLY); 
    printf("Opened %d for writing\n", fd); 
    sleep(3); 
    close(fd); 
    } else { 
    int fd = open(filename, O_RDONLY); 
    printf("Opened %d for reading\n", fd); 

    static const int MAX_LENGTH = 1; 
    struct epoll_event init; 
    struct epoll_event evs[MAX_LENGTH]; 
    int efd = epoll_create(MAX_LENGTH); 

    int i; 
    for (i = 0; i < MAX_LENGTH; ++i) { 
     init.data.u64 = 0; 
     init.data.fd = fd; 
     init.events |= EPOLLIN | EPOLLPRI | EPOLLHUP; 
     epoll_ctl(efd, EPOLL_CTL_ADD, fd, &init); 
    } 

    while (1) { 
     int nfds = epoll_wait(efd, evs, MAX_LENGTH, -1); 
     printf("%d fds ready\n", nfds); 
     int nread = read(fd, buf, sizeof(buf)); 
     if (nread < 0) { 
     perror("read"); 
     exit(1); 
     } else if (!nread) { 
     printf("Child %d closed the pipe\n", pid); 
     break; 
     } 
     printf("Reading: %s\n", buf); 
    } 
    } 
    return 0; 
} 

但是,我这样做是与另一位读者(其代码我没有特权发布的时候,但是这使得完全相同的调用 - 玩具程序是模仿它的),当作者关闭fifo时,过程不会醒来。玩具阅读器还提供了所需的语义select。配置为使用select的真实读卡器也会失败。

什么可能占了两个不同的行为?对于任何提供的假设,我如何验证它们?我正在运行Linux 2.6.38.8。

回答

0

strace是确认系统调用是否正确调用(即参数正确传递并且不会返回任何意外错误)的绝佳工具。

除此之外,我建议使用lsof来检查没有其他进程有该FIFO仍然打开。

+0

道歉的(极)迟了回应。前锋队确实是开放的,而且我帮助我看到了它。 – AlexK