我有两个通过命名管道进行通信的C ++程序(使用mkfifo()生成)。
一段时间后,编写程序挂起。我认为FIFO的缓冲区已满。 如果缓冲区已满,是否可以在写入FIFO之前进行检查?
提前致谢!
鲁
答案 0 :(得分:3)
我担心O_NONBLOCK
写入命名的fifo会导致linux上出现内存不足的问题:
我做了一个小实验,当作家处理时会发生什么......
SIGPIPE
)的过程信号设置为忽略,O_NONBLOCK
这实际上是在作者程序本身中整合了ftee-program posted here的想法。
另一方面,我会在相当长的一段时间后读出命名的fifo的内容到文件中并检查它 - 因此我的意思是“在写入程序生成了超过64K的数据之后”。
结果是,该文件包含编写进程的所有输出 - 这证明了linux已经缓冲了超过64K的文件。
这给我提出了一些问题:
背景: - 那是我的作家程序writer.pl
:
#!/usr/bin/perl -w
use strict;
use Fcntl;
my $fifo_name = '/tmp/fifo1';
sub daemon()
{
my $pid = fork();
if ($pid < 0) { die "fork(): $! \r\n"; }
if ($pid > 0) { exit(0); }
close(STDIN);
close(STDOUT);
}
sub main()
{
`mkfifo $fifo_name`;
$SIG{'PIPE'} = "IGNORE"; # ignoring SIGPIPE
my $fifo_fh = undef;
sysopen($fifo_fh, $fifo_name, O_NONBLOCK | O_RDWR) or die $!;
my $n = 0;
while (1)
{
my $line = "This is line $n...\n";
syswrite($fifo_fh, $line, length($line));
select(undef, undef, undef, 0.01); # sleep 1/100 second
$n++;
}
}
daemon();
main();
......那就是我测试过的:
$ ./writer.pl
......等一会儿......
$ cat /tmp/fifo1 > dump.txt
...因为这永远不会终止,一段时间后按Ctrl-C,然后
$ less dump.txt
This is line 0...
This is line 1...
This is line 2...
...
This is line 61014...
This is line 61015...
自开始以来,writer.pl的所有输出都存储在某处!
答案 1 :(得分:2)
如果进程尝试写入完整管道(见下文),那么 写入(2)块直到从管道读取足够的数据 允许写完成。
解决方案是打开指定O_NONBLOCK
标志的管道(请参阅open
man page)。