C ++ Linux中的命名管道检查缓冲区是否已满

时间:2013-05-24 09:06:27

标签: c++

我有两个通过命名管道进行通信的C ++程序(使用mkfifo()生成)。

一段时间后,编写程序挂起。我认为FIFO的缓冲区已满。 如果缓冲区已满,是否可以在写入FIFO之前进行检查?

提前致谢!

2 个答案:

答案 0 :(得分:3)

我担心O_NONBLOCK写入命名的fifo会导致linux上出现内存不足的问题:

我做了一个小实验,当作家处理时会发生什么......

  • 将断开的管道(SIGPIPE)的过程信号设置为忽略,
  • 使用O_NONBLOCK
  • 打开命名管道
  • 然后将大量内容写入该管道。

这实际上是在作者程序本身中整合了ftee-program posted here的想法。

另一方面,我会在相当长的一段时间后读出命名的fifo的内容到文件中并检查它 - 因此我的意思是“在写入程序生成了超过64K的数据之后”。

结果是,该文件包含编写进程的所有输出 - 这证明了linux已经缓冲了超过64K的文件。

这给我提出了一些问题:

  • 是否有超出64K命名管道缓冲区大小的另一个限制?
  • 或者它会增加,直到linux内存耗尽?

背景: - 那是我的作家程序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)

来自pipe man page

  

如果进程尝试写入完整管道(见下文),那么   写入(2)块直到从管道读取足够的数据   允许写完成。

解决方案是打开指定O_NONBLOCK标志的管道(请参阅open man page)。