Perl - 多线程/分叉/同步问题:

Perl - multithreading / fork / synchronize problem:

我正在尝试作为以下代码的示例:

    my $milon;
    my $pid = fork();
    die if not defined $pid;    
    if (not $pid) 
    {
        $milon->{$pid} = $pid;
        exit;
    }
    
    $milon->{3} = 4;        
    my $finished = wait();  
    print( "debug10: TEST = ", Dumper($milon));

输出:

debug10: TEST = $VAR1 = {
          '3' => 4
        };

如何让字典同时保留 3 => 4$pid => $pid? 不一定非要fork,可以是多线程也可以是NonBlocking IO,看你觉得哪个好。

当然这是一个例子,我只是想从这个例子总结到我的真实代码。

您需要一些 threads/processes 共享的内存。最简单的可能是使用基于解释器的 threads and threads::shared。例如:

use threads;
use threads::shared;

my %milon :shared;

for (1 .. 2) {
    threads->create(sub {
        my $tid = threads->tid();
        $milon{$tid} = $tid;
    });
}

$milon{3} = 4;

$_->join for threads->list; # Wait for all threads to be done

print Dumper \%milon;

这输出:

$VAR1 = {
          '1' => 1,
          '2' => 2,
          '3' => 4
        };

以下示例代码演示了如何使用 fork() 在并行执行中计算数组 @numbers(总共 100)中数字的 平方

REAPER 分配给 $SIG{CHLD} 信号的函数清理已完成的 子进程 以避免 zombie 进程徘徊处理中 table.

调查 fork() 方法是否适合您的 problem/task。

use strict;
use warnings;

use POSIX qw(strftime :sys_wait_h);
use Time::HiRes qw(usleep);

my $limit   = 10;
my $threads = $limit;
my @numbers = map { int(rand(100)) } 1..100;

sub REAPER {
    local $!;

    while( (my $pid = waitpid(-1, WNOHANG) ) > 0 && WIFEXITED($?) ) {
        $threads++;
    }

    $SIG{CHLD} = \&REAPER;
}

$SIG{CHLD} = \&REAPER;

for ( @numbers ) {
    while( $threads == 0 or $threads > $limit ) { usleep(1) }

    my $pid = fork();

    die $! unless defined $pid;

    if( $pid ) {
        # parent
        $threads--;
    } else {
        # child
        my $n = compute_square($_);
        printf "Process %6d: %3d => %d\n", $$, $_, $n;
        exit 0;
    }
}

sub compute_square {
    my $num = shift;

    return $num*$num;
}