共享内存和分叉

时间:2014-05-05 07:41:30

标签: perl shared-memory fork

我正在使用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);
}

2 个答案:

答案 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;
    }
}