尝试从多个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
}
}
}
答案 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缓冲区)。