Can';无法从多个FIFO读取数据

Can';无法从多个FIFO读取数据,c,linux,named-pipes,C,Linux,Named Pipes,我在尝试读取多个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, &am

我在尝试读取多个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)
{
}
这在信号处理器中

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
       }

    }
  }
myfifo[i]=/tmp/myfifo{0}/{0}是i,它是发送的进程数。
而(1)
{
对于(i=0;i 1)
{
//printf结构元素
}
}
}

打开并读取以下内容后,您不会关闭文件描述符:

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
       }

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

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

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
       }

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

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

我建议打开循环外的所有FIFO,将文件描述符存储在一个数组中,然后只读取每个文件描述符,但是。。。读取将被阻止。请参阅
选择(2)
,了解哪个FIFO有数据


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

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

我建议打开循环外的所有FIFO,将文件描述符存储在一个数组中,然后只读取每个文件描述符,但是。。。读取将被阻止。请参阅
选择(2)
,了解哪个FIFO有数据


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

请发送一个最小的工作示例。例如,您是否在读取过程中打开fd后再次关闭每个fd?否则,您很快就会用完文件描述符。这大部分是其他正在打印和设置目录的内容。我建议阅读
man 7 fifo
的输出,特别是关于在非阻塞模式下打开fifo的部分。我认为当FIFO的另一端未打开时,您的只写、非阻塞
open
s将因errno
ENXIO
而失败。请发送一个最小的工作示例。例如,您是否在读取过程中打开fd后再次关闭每个fd?否则,您很快就会用完文件描述符。这大部分是其他正在打印和设置目录的内容。我建议阅读
man 7 fifo
的输出,特别是关于在非阻塞模式下打开fifo的部分。我认为当FIFO的另一端未打开时,您的只写、非阻塞的
open
s将失败,并出现errno
ENXIO
。这仍然没有帮助,如果我不发送给myfifo[0],其他FIFO将不会成功read@Thomas对不起,我不明白这条评论,你能再详细说明一下发生了什么吗?myfifo[0]有第一个fifo的路径,如果我不阅读,我不会检查下一个。例如,如果我先发送到myfifo[2](第三条路径),它将等待直到myfifo[0]和myfifo[1]被读取。@Thomas据我所知,这样做的原因超出了您提供的代码段的范围。或者你误解了你所看到的。我只能建议您,提供一个可以实际编译和测试的最小示例。我想我找到了一种方法,删除管道。。虽然我对结果不是很满意。我会知道事情的进展。稍后我会提供我的答案。这仍然没有帮助,如果我不发送给我的FIFO[0],其他FIFO将不会被删除read@Thomas很抱歉,我不理解这条评论,你能详细说明一下会发生什么吗?myfifo[0]有第一个fifo的路径,如果我不阅读它,我不会检查下一个。例如,如果我先发送到myfifo[2](第三条路径),它将等待直到myfifo[0]和myfifo[1]被读取。@Thomas据我所知,这样做的原因超出了您提供的代码段的范围。或者你误解了你所看到的。我只能建议您,提供一个可以实际编译和测试的最小示例。我想我找到了一种方法,删除管道。。虽然我对结果不是很满意。我会知道事情的进展。稍后我会提供我的答案。