我正在使用fork创建9个进程,我想让它运行:4次打印“a selected。”,3次打印“b selected”,2次打印“c selected”。为此我需要减少每个运行情况的计数器,我需要使用共享内存,但不知道如何,你能帮忙吗?
#!/usr/intel/bin/perl5.14.1
my $all_running = 9; #2+3+4
my @times_to_run = (4, 3, 2);
my (@children, @non_empty_cells);
# make an array which will save the indexes of cells in @times_to_run which aren't empty
for (my $i = 0; $i < scalar(@times_to_run); $i++) {
if ($times_to_run[$i] != 0) {
push(@non_empty_cells, $i);
}
}
while ($all_running > 0) { #run 5 times
my $pid = fork();
if (!defined($pid)) {
print("Fork Failed\n");
}
elsif ($pid > 0) {
#parent
push(@children, $pid);
sleep(0.5);
}
else { # child
# pick a non-empty cell
my $random_ = int(rand(@non_empty_cells));
if ($non_empty_cells[$random_] == 0) {
print "a chosen\n";
$times_to_run[0]--;
print "now $times_to_run[0]\n";
}
elsif ($non_empty_cells[$random_] == 1) {
print "b chosen \n";
$times_to_run[1]--;
print "now $times_to_run[1]\n";
}
else {
print "c chosen\n";
$times_to_run[2]--;
print "now $times_to_run[2]\n";
}
# update non empty-cells array
@non_empty_cells = ();
for (my $i = 0; $i < scalar(@times_to_run); $i++) {
if ($times_to_run[$i] != 0) {
push(@non_empty_cells, $i);
}
}
# print "now empty cells is : ".scalar(@non_empty_cells)."\n\n";
exit 0;
}
$all_running--;
}
foreach (@children) {
my $tmp = waitpid($_, 0);
}
答案 0 :(得分:0)
如果没有这么做,只需在每个if条件中杀死一个进程。因此,在4个过程打印“选择”后,1个被杀死,因此“b选择将被打印3次”。你需要使用他们的PID来杀死进程。
答案 1 :(得分:0)
如果你绝对想要共享内存,有很多方法可以获得它:shmget
, IPC::Sharable
, forks::shared
, ...
但在你的情况下,这肯定是矫枉过正的。您可以在分叉之前简单地将所需的任何内容分配给一个变量,如下所示:
my @test = qw( a b c );
for my $test (@test) {
my $pid = fork;
if (!$pid) {
say $test;
exit;
}
}
或者,更接近你的榜样:
use List::Util qw(shuffle);
my @test = shuffle (('a chosen') x 4, ('b chosen') x 3, ('c chosen') x 2);
for my $test (@test) {
my $pid = fork;
if (!$pid) {
say $test;
exit;
}
}