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;
}
我正在尝试作为以下代码的示例:
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;
}