Perl:从并行线程派生
Perl: fork from parallel threads
下面的代码应该是 运行 2 个并行线程,每个线程执行 fork(),等待子进程完成,然后线程应该加入(完成)并打印结果。
实际上,第一个分叉子进程按预期完成,但第二个子进程挂在 _mutex_lock() 试图退出,因此第二个线程永远不会加入,直到您使用 -9 信号手动杀死第二个子进程。
有人可以解释为什么会发生这种情况,以及如何避免这种情况吗?
use strict;
use warnings;
use threads;
use Data::Dumper;
sub Run
{
my $tid = threads->tid();
my $log = {};
$log->{"[$$:$tid]:00"} = "started";
my $pid = fork();
if ($pid == 0)
{
print "In child ($$): started\n";
sleep 3;
print "In child ($$): finished\n";
# system("kill -9 $$"); -- brutal way
exit 0;
}
waitpid($pid, 0);
my $exitCode = $? >> 8;
$log->{"[$$:$tid]:01"} = "finished, code=$exitCode";
return $log;
}
my @threads = ();
foreach (1..2)
{
push @threads, threads->new(sub { return Run() });
}
print Dumper($_->join()) for @threads;
在我的 Linux 盒子上,使用 POSIX instead of exit 中的 _exit
是可行的。不过,此解决方案可能无法移植到其他平台。
链接的文档说:
Note that when using threads and in Linux this is not a good way to exit a thread because in Linux processes and threads are kind of the same thing (Note: while this is the situation in early 2003 there are projects under way to have threads with more POSIXly semantics in Linux). If you want not to return from a thread, detach the thread.
同样,perlthrtut - Tutorial on threads in Perl说
Thinking of mixing fork() and threads? Please lie down and wait until the feeling passes. Be aware that the semantics of fork() vary between platforms. For example, some Unix systems copy all the current threads into the child process, while others only copy the thread that called fork(). You have been warned!
下面的代码应该是 运行 2 个并行线程,每个线程执行 fork(),等待子进程完成,然后线程应该加入(完成)并打印结果。 实际上,第一个分叉子进程按预期完成,但第二个子进程挂在 _mutex_lock() 试图退出,因此第二个线程永远不会加入,直到您使用 -9 信号手动杀死第二个子进程。 有人可以解释为什么会发生这种情况,以及如何避免这种情况吗?
use strict;
use warnings;
use threads;
use Data::Dumper;
sub Run
{
my $tid = threads->tid();
my $log = {};
$log->{"[$$:$tid]:00"} = "started";
my $pid = fork();
if ($pid == 0)
{
print "In child ($$): started\n";
sleep 3;
print "In child ($$): finished\n";
# system("kill -9 $$"); -- brutal way
exit 0;
}
waitpid($pid, 0);
my $exitCode = $? >> 8;
$log->{"[$$:$tid]:01"} = "finished, code=$exitCode";
return $log;
}
my @threads = ();
foreach (1..2)
{
push @threads, threads->new(sub { return Run() });
}
print Dumper($_->join()) for @threads;
在我的 Linux 盒子上,使用 POSIX instead of exit 中的 _exit
是可行的。不过,此解决方案可能无法移植到其他平台。
链接的文档说:
Note that when using threads and in Linux this is not a good way to exit a thread because in Linux processes and threads are kind of the same thing (Note: while this is the situation in early 2003 there are projects under way to have threads with more POSIXly semantics in Linux). If you want not to return from a thread, detach the thread.
同样,perlthrtut - Tutorial on threads in Perl说
Thinking of mixing fork() and threads? Please lie down and wait until the feeling passes. Be aware that the semantics of fork() vary between platforms. For example, some Unix systems copy all the current threads into the child process, while others only copy the thread that called fork(). You have been warned!