понедельник, 28 декабря 2009 г.

Open, каналы и ожидание завершения потомка

Трудно искать черную кошку в темной комнате, особенно, если ее там нет.
Но как оказалось, еще трудней не замечать черную кошку, сидящую на видном месте в ярко освещенной комнате!

Так вот и я потратил приличную часть времени, заметив, что в коде, упрошенном до нижеследующего, родительский процесс ожидает завершения потомка:

my $child_sub = sub { sleep };

my $child_pid = open my $fh, "-|";
defined $child_pid or die "Can't fork: $!";

if ($child_pid) {
# Родитель.
} else {
# Ребенок.
$child_sub->();
exit;
}

Впредь, если для дочернего процесса может истечь тайм-аут, буду использовать вызов pipe:

my $child_sub = sub { sleep };

pipe my $from_child_fh, my $to_parent_fh or die "pipe: $!";

my $child_pid = fork;
defined $child_pid or die "Can't fork: $!";

if ($child_pid) {
# Родитель.
close $to_parent_fh;
} else {
# Ребенок.
close $from_child_fh;
$child_sub->();
exit;
}

Или буду использовать socketpair.

С другой стороны, вред от первого варианта на практике всегда отсутствует, наверно поэтому и не замечал этого явления на протяжении многих лет.

Комментариев нет: