命名管道在c++ Linux检查缓冲区是否已满

Named Pipe in C++ Linux check if buffer is full

本文关键字:缓冲区 是否 检查 Linux 管道 c++      更新时间:2023-10-16

我有两个c++程序通过命名管道(由mkfifo()生成)进行通信。

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

提前感谢!

鲁本

From pipe手册页:

如果一个进程试图写一个完整的管道(见下文),那么写(2)块,直到从管道中读取了足够的数据允许写操作完成

解决方案是打开指定O_NONBLOCK标志的管道(参见open手册页)。

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

我做了一个小实验,会发生什么,当作者进程…

  • 设置管道破裂(SIGPIPE)的进程信号为忽略,
  • 使用O_NONBLOCK
  • 打开命名管道
  • ,然后将很多东西写入该管道。

这实际上是将这里发布的ftee-program的思想集成到writer程序本身中。

另一方面,我将在相当长一段时间后将命名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(): $! rn"; }    
    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自开始以来的所有输出都存储在某处!