简体   繁体   English

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

[英]Named Pipe in C++ Linux check if buffer is full

I have two C++ Programs communicating over named pipes (generated with mkfifo()). 我有两个通过命名管道进行通信的C ++程序(由mkfifo()生成)。

After some time the writing program hangs. 一段时间后,编写程序挂起。 I think the buffer of FIFO is full. 我认为FIFO的缓冲区已满。 Is it possible to check before writing to FIFO if buffer is full? 是否可以在写入FIFO之前检查缓冲区是否已满?

Thanks in advance! 提前致谢!

Ruben 鲁本

I am afraid that the O_NONBLOCK writing into a named fifo will lead to a out-of-memory-problem on linux: 恐怕O_NONBLOCK写入命名的fifo会导致linux内存不足的问题:

I made a little experiment, what will happen, when the writer process... 我做了一个小实验,当编写程序时会发生什么...

  • sets the process signal for broken pipe ( SIGPIPE ) to ignore, 将断管的过程信号( SIGPIPE )设置为忽略,
  • opens a named pipe with O_NONBLOCK O_NONBLOCK打开一个命名管道
  • and then writes a lot of stuff into that pipe. 然后将很多东西写入该管道。

This is actually integrating the idea of the ftee-program posted here in the writer program itself. 这实际上是将在此处发布ftee程序的思想整合到writer程序本身中。

On the other side, i will read out the content of the named fifo after quite a while into a file and examine it - thereby i mean "after the writer process has produced way more than 64K of data". 另一方面,我将在相当长的一段时间后将命名的fifo的内容读出到文件中并进行检查-因此,我的意思是“在编写器进程产生了超过64K的数据之后”。

result is, that the file contains all the output of the writer process - this proves that way more than 64K have been buffered by linux. 结果是该文件包含writer进程的所有输出-这证明linux已经缓冲了64K以上的方式。

This poses some questions to me: 这给我提出了一些问题:

  • is there another limit beyond the 64K named pipe buffer size? 除了64K命名管道缓冲区的大小,还有其他限制吗?
  • or willl it increase until linux runs out of memory? 还是会增加直到Linux内存不足?

Background: - that is my writer program writer.pl : 背景:-这是我的作家程序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();

... and thats what i tested: ...这就是我测试的内容:

$ ./writer.pl

... wait a while ... ... 等一会儿 ...

$ cat /tmp/fifo1 > dump.txt

... since this will never terminate, hit Ctrl-C after a while, then ...由于这将永远不会终止,请过一会儿再按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...

All output of writer.pl since the beginning was stored somewhere! 自开始以来,writer.pl的所有输出都存储在某个地方!

From pipe man page : pipe手册页

If a process attempts to write to a full pipe (see below), then write(2) blocks until sufficient data has been read from the pipe to allow the write to complete. 如果某个进程尝试写入一个已满的管道(请参见下文),则write(2)会阻塞,直到从管道中读取了足够的数据以允许写入完成为止。

The solution is to open the pipe specifying the O_NONBLOCK flag (see open man page ). 解决方案是打开指定O_NONBLOCK标志的管道(请参见open手册页 )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM