2016-01-12 60 views
0

尝试从多个FIFO中读取时,我遇到了一个非常恼人的问题。我有1个进程等待来自fifo的结构,很少有进程将这些结构发送给信号。在第一次阅读后,我无法从任何信号中读出更多。它看起来像程序冻结。无法从多个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 
     } 

    } 
    } 
+0

请发送一个简单的工作示例。例如,您是否在打开_reading process_后再次关闭每个fd?否则,你将很快用完文件描述符 – Ctx

+0

,这大部分是其他事物正在打印和设置目录的一切。 – Thomas

+0

我建议读取'man 7 fifo'的输出,特别是关于在非阻塞模式下打开FIFO的部分。我认为当FIFO的另一端没有打开时,你的只写,非阻塞的'open'将会失败,并带有errno'ENXIO'。 –

回答

1

你不打开后关闭filedescriptors和阅读:

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)

} 
} 

由于开放是非阻塞的,很快会达到每过程FDS的最大数量,以及随后的打开将失败。

+0

这仍然没有帮助,如果我不会发送到myfifo [0]其他fifos不会被读取 – Thomas

+0

@Thomas对不起,我不明白这个评论,请你详细说明会发生什么? – Ctx

+0

myfifo [0]有路径到第一个fifo,如果我不读取它,我不会检查下一个。 例如,如果我首先发送myfifo [2](第三条路径),它将等待unipher myfifo [0]和myfifo [1]被读取。 – Thomas

1

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

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

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