2014-05-05 130 views
-3

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

沒有這麼多,只要在每個條件中殺死一個進程即可。因此,在4個過程打印出「一個選定的」後,1個被殺死,所以「b選擇將打印3次」。你需要用PID來殺死進程。

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; 
    } 
} 
+0

謝謝,但我希望它選擇一個隨機每次(ab或c)。這就是爲什麼我需要一個計數器來計算每個人已經打印的數量。 – user3595059

+0

@ user3595059,你是否需要*在子進程內發生的隨機性?因爲在分岔之前「洗牌」數組(或者使用「rand」,如果你更喜歡它的話)會更容易。 – scozy

+0

你,你是對的:) 我做了隨機之前,並沒有共享內存。謝謝! – user3595059