Reputation: 21
I have two C++ Programs communicating over named pipes (generated with mkfifo()).
After some time the writing program hangs. I think the buffer of FIFO is full. Is it possible to check before writing to FIFO if buffer is full?
Thanks in advance!
Ruben
Upvotes: 2
Views: 3678
Reputation: 59
I am afraid that the O_NONBLOCK
writing into a named fifo will lead to a out-of-memory-problem on linux:
I made a little experiment, what will happen, when the writer process...
SIGPIPE
) to ignore, O_NONBLOCK
This is actually integrating the idea of the ftee-program posted here in the writer program itself.
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".
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.
This poses some questions to me:
Background: - that is my writer program 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
$ 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!
Upvotes: 1
Reputation: 10947
From pipe
man page :
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.
The solution is to open the pipe specifying the O_NONBLOCK
flag (see open
man page).
Upvotes: 2