无法读取多个fifos

时间:2016-01-12 14:48:18

标签: c linux named-pipes

尝试从多个fifos中读取时,我遇到了一个非常烦人的问题。我有一个进程等待来自fifo的结构和几个正在向他发送信号结构的进程。在第一次阅读后,我无法阅读任何信号。看起来程序冻结了。

发送过程主要有

myfifo = '/tmp/myfifo{0}' //{0} is a number that every process has individual.
mkfifo(myfifo, 0666);
fd = open(myfifo, O_WRONLY);
write(fd, &demon1 , sizeof(demon1));
close(fd);
while (1)
{
}

,这在signal_handler

void signal_handler(int signum)
{
    if (signum == SIGUSR1)
    {
        //some declarations here
        mkfifo(myfifo, 0666);
        fd = open(myfifo, O_WRONLY | O_NONBLOCK);
        write(fd, &demon1 , sizeof(demon1));
    }
}

虽然阅读过程已经

myfifo[i] = /tmp/myfifo{0} // {0} is i which is the number of process that sends.

 while(1)
 {
    for(i=0;i<n;i++)
    {
       fd = open(myfifo[i], O_RDONLY | O_NONBLOCK);
       r = read(fd, &demon1, sizeof(demon1));
       if(r > 1)
       {
           //printf struct elements
       }

    }
  }

2 个答案:

答案 0 :(得分:1)

打开并阅读后,您不会关闭文件描述符:

while(1)
{
    for(i=0;i<n;i++)
    {
       fd = open(myfifo[i], O_RDONLY | O_NONBLOCK);
       r = read(fd, &demon1, sizeof(demon1));
       if(r > 1)
       {
           //printf struct elements
       }

此处缺少close(fd)

    }
}

由于open是非阻塞的,因此很快就会达到每个进程的最大fds数,后续打开将失败。

答案 1 :(得分:1)

打开循环内的管道。这样,您很快就会用完文件描述符(如果您检查open()的错误结果,就会看到这些描述符。)

我建议打开循环外的所有FIFO,将文件描述符存储在一个数组中,然后只读取它们中的每一个但读取将阻塞。请参阅select(2)以找出哪个FIFO有数据。

另一种解决方案是单个FIFO,写入过程应该在消息中发送它的ID。这样,主进程只需要监听单个FIFO。如果它想知道谁发送了消息,它可以查看消息中的ID。问题在于:您需要某种锁定或多个进程同时写入FIFO并且它们的数据可以混淆(这取决于FIFO缓冲区)。