Can';无法从多个FIFO读取数据
我在尝试读取多个FIFO时遇到了一个非常恼人的问题。我有一个进程等待来自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
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将因errnoENXIO
而失败。请发送一个最小的工作示例。例如,您是否在读取过程中打开fd后再次关闭每个fd?否则,您很快就会用完文件描述符。这大部分是其他正在打印和设置目录的内容。我建议阅读man 7 fifo
的输出,特别是关于在非阻塞模式下打开fifo的部分。我认为当FIFO的另一端未打开时,您的只写、非阻塞的open
s将失败,并出现errnoENXIO
。这仍然没有帮助,如果我不发送给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据我所知,这样做的原因超出了您提供的代码段的范围。或者你误解了你所看到的。我只能建议您,提供一个可以实际编译和测试的最小示例。我想我找到了一种方法,删除管道。。虽然我对结果不是很满意。我会知道事情的进展。稍后我会提供我的答案。