in reply to Socketpair and a lot of children
#! /usr/bin/env perl package Foo::Child; use strict; use warnings; use FileHandle; sub new { my ($class, $pfh, $cfh, $f, @args) = @_; bless {pfh => $pfh, cfh => $cfh, f => $f, args => [$pfh, @args]}, $class; } sub run_and_die { my ($fc) = @_; close $fc->{cfh}; $fc->{f}->($fc, @{$fc->{args}}); close $fc->{pfh}; exit; } sub cfh { $_[0]->{cfh} } sub pfh { $_[0]->{pfh} } package Foo; use strict; use warnings; use Socket; use FileHandle; sub new { bless {children => []}, shift } sub add_child { my ($foo, $f, @args) = @_; my ($cfh, $pfh) = (FileHandle->new, FileHandle->new); $_->autoflush(1) for ($cfh, $pfh); socketpair $cfh, $pfh, AF_UNIX, SOCK_STREAM, PF_UNSPEC or die "socketpair: $!"; push @{$foo->{children}}, Foo::Child->new($pfh, $cfh, $f, @args); $foo } sub run { my ($foo) = @_; for my $c (@{$foo->{children}}) { for (fork) { die "fork failed: $!" unless defined; $c->run_and_die unless $_; close $c->pfh; } } $foo } sub to_all { my ($foo, $s) = @_; print { $_->cfh } $s for @{$foo->{children}}; $foo } sub from_all { my ($foo, @r) = (shift); for (@{$foo->{children}}) { chomp(my $s = readline($_->cfh)); push @r, $s } @r } package main; sub echo_reverse { my ($self, $pfh, $times) = @_; while ($times--) { chomp(my $line = readline($pfh)); print $pfh reverse($line) . "\n"; } } my $echos = new Foo; $echos->add_child(\&echo_reverse, 1) for (1..10); $echos->run; $echos->to_all("hello world!\n"); print "Read this from a child: $_\n" for $echos->from_all;
If you want to have a really good time, set the number of children to 1 or 2 and then run this program through the perl debugger. In X, at least, I thought this very cool.
Also, a koders search for socketpair in Perl code.
|
|---|