#!/opt/perl/bin/perl use strict; use AnyEvent; use POSIX; use IO::Handle; use Time::HiRes qw/usleep/; pipe my $par, my $chld; $par->autoflush (1); $chld->autoflush (1); my $pid = fork; defined $pid or die "fork failed: $!"; if ($pid) { # parent: # first we create a condition variable, which allows # us to wait for a 'condition' to become true. my $cvar = AnyEvent->condvar; # then we setup a watcher which will watch for the 'readable' # event for the parent end of the pipe. The callback we # pass will be executed when the filehandle becomes readable. my $read_watcher = AnyEvent->io (fh => $par, poll => 'r', cb => sub { my $r = sysread $par, my $data, 1024; if (not defined $r) { $! == EAGAIN and return; die "sysread failed: $!"; } else { print "Data from child: [\n$data]\n"; } }); # after that a child watcher will be installed, where we wait # for the child to terminate. (AnyEvent installs a SIGCHLD handler # for us here). my $child_watcher = AnyEvent->child (pid => $pid, cb => sub { print "Child terminated\n"; # when the child terminated we are finished, and the broadcast # method will let the call to 'wait' below return. $cvar->broadcast; }); # here we start to wait for the 'broadcast' in the child # watcher. Under the hood AnyEvent starts one of the available # event loops for us (might be Glib, Event, EV, Tk or even it's # own pure Perl implementation via select(), depending on what is # available or loaded). $cvar->wait; } else { # child: my $cnt = 0; while (1) { usleep ((int rand (500000)) + 100000); syswrite $chld, "iteration count: ".++$cnt."\n" or die "write not successful: $!"; if ($cnt > 10) { exit 0 } } } #### use EV; use AnyEvent; # ... my $child_watcher = AnyEvent->child (pid => $pid, cb => sub { print "Child terminated\n"; EV::unloop; }); EV::loop;