Если я правильно понимаю.
- Вы хотите предотвратить B от создания E и F до D создается A .
- Вы хотите запретить C создавать G до F создается B .
Это означает, что
- B должно ждать сообщения от D или A (с указанием D было создано) до создания E и F .
- C должен дождаться сообщения от F или B (указывая, что F был создан), прежде чем создавать G .
Слово сообщение здесь используется очень свободно. Я имею в виду некоторую форму передачи информации.
Здесь можно эффективно использовать трубу. Скажем, что R (получатель) должен ждать создания S (отправитель).
- Имеет S закрыть запись конец трубы.
- Пусть R ждут EOF, прежде чем продолжить.
Существуют два обстоятельства, при которых R будет продолжаться:
- S было создано.
- S никогда не будет создано (из-за cra sh или чего-то еще).
Таким образом, этот подход является "cra sh -защищенным", что означает, что у вас не будет процессов, ожидающих вечно, если что-то не так. И если вы захотите, вы можете даже различить guish обстоятельства, передав S байт перед закрытием канала. Отлично.
Это просто вопрос закрытия ручек труб в нужное время. Ниже приведена демонстрация вашей цели. (Это написано в Perl, но pipe
, fork
, waitpid
, sleep
и close
- просто тонкие оболочки для функций C с тем же именем. Просто игнорируйте $
. )
#!/usr/bin/perl
use strict;
use warnings;
use feature qw( say );
sub fork_child {
my $sub = shift;
my $pid = fork();
if (!$pid) {
if (!eval { $sub->(@_); 1 }) {
warn( eval { "$@" } // "Unknown error" );
exit(($? >> 8) || $! || 255);
}
exit(0);
}
return $pid;
}
sub a {
$0 = "a";
say "$0 is pid $$";
pipe(my $d_created_recver, my $d_created_sender);
pipe(my $f_created_recver, my $f_created_sender);
my $pid_b = fork_child(\&b, $d_created_recver, $d_created_sender, $f_created_recver, $f_created_sender);
my $pid_c = fork_child(\&c, $d_created_recver, $d_created_sender, $f_created_recver, $f_created_sender);
my $pid_d = fork_child(\&d, $d_created_recver, $d_created_sender, $f_created_recver, $f_created_sender);
close($_) for $d_created_recver, $d_created_sender, $f_created_recver, $f_created_sender;
waitpid($pid_b, 0);
waitpid($pid_c, 0);
waitpid($pid_d, 0);
}
sub b {
my ($d_created_recver, $d_created_sender, $f_created_recver, $f_created_sender) = @_;
$0 = "b";
say "$0 is pid $$";
# Not related to B or its descendants.
close($_) for $d_created_sender, $f_created_recver;
# Wait for D to be created.
read($d_created_recver, my $buf, 1);
close($d_created_recver);
my $pid_e = fork_child(\&e, $f_created_sender);
my $pid_f = fork_child(\&f, $f_created_sender);
# Allow G to be created.
close($f_created_sender);
waitpid($pid_e, 0);
waitpid($pid_f, 0);
}
sub c {
my ($d_created_recver, $d_created_sender, $f_created_recver, $f_created_sender) = @_;
$0 = "c";
say "$0 is pid $$";
# Not related to C or its descendants.
close($_) for $d_created_sender, $d_created_recver, $f_created_sender;
# Wait for F to be created.
read($f_created_recver, my $buf, 1);
close($f_created_recver);
my $pid_g = fork_child(\&g);
waitpid($pid_g, 0);
}
sub d {
my ($d_created_recver, $d_created_sender, $f_created_recver, $f_created_sender) = @_;
$0 = "d";
say "$0 is pid $$";
# Not related to D or its descendants.
close($_) for $d_created_recver, $f_created_sender, $f_created_recver;
# Allow E to be created.
close($d_created_sender);
sleep();
}
sub e {
my ($f_created_sender) = @_;
$0 = "e";
say "$0 is pid $$";
# Not related to E process or its decendants.
close($f_created_sender);
sleep();
}
sub f {
my ($f_created_sender) = @_;
$0 = "f";
say "$0 is pid $$";
# Allow G to be created.
close($f_created_sender);
sleep();
}
sub g {
$0 = "g";
say "$0 is pid $$";
my $pid_i = fork_child(\&i);
waitpid($pid_i, 0);
}
sub i {
$0 = "i";
say "$0 is pid $$";
sleep();
}
a();
Выход: