How can I prevent a parent from blocking while writing to a child?

I recently had a problem using (pipe | -) when I wanted to establish a connection between two processes. Basically, the child process could not process the STDIN as fast as it was populated by the parent. This made the parent wait until STDIN became free and made it slow.

How big can an STDIN be, and is it possible to modify it. If so, what is the size of the best practice?

Here is a sample code to show what I mean:

if ($child_pid = open($child, "|-"))
{
    $child->autoflush(1);

    # PARENT process
    while (1)
    {

             # Read packet from socket save in $packet
             process_packet($packet);

             # forward packet to child
             print $child $packet;
     }
}
else
{
     die "Cannot fork: $!" unless defined $child_pid;
     # CHILD process
     my $line;  

     while($line = <STDIN>)
     {
         chomp $line;
         another_process_packet($line);
     }
}

In this example, another_process_packetslower than process_packet. The reason I write this code is because I want to use the same data from the socket and actually get it once.

Thanks in advance.

+3
3

, , , fd (.. ). syswrite :

use AnyEvent;
use AnyEvent::Handle;

# make child, assume you write to it via $fh

my $done = AnyEvent->condvar;
my $h = AnyEvent::Handle->new( fh => $fh );

while( you do stuff ){
    my $data = ...;
    $h->push_write($data); # this will never block
}

$h->on_drain(sub { $done->send });
$done->wait; # now you block, waiting for all writes to actually complete

: , , . ( perl -ne "sleep 1; print $_" .) while, , . .

gist.github: http://gist.github.com/126488

, , . , ;)

(, , , , .)

+6

. ​​ .

+1

The process handler contains a member function called "lock". Just set the lock to 0 and the parent process will not be locked.

if ($child_pid = open($child, "|-"))
{
    $child->blocking(0);    # Key to the solution.
    $child->autoflush(1);

    # PARENT process
    while (1)
    {

             # Read packet from socket save in $packet
             process_packet($packet);

             # forward packet to child
             print $child $packet;
     }
}
else
{
     die "Cannot fork: $!" unless defined $child_pid;
     # CHILD process
     my $line;  

     while($line = <STDIN>)
     {
         chomp $line;
         another_process_packet($line);
     }
}
0
source

Source: https://habr.com/ru/post/1710059/


All Articles