【问题标题】:Perl: fork from parallel threadsPerl:从并行线程派生
【发布时间】:2020-02-11 08:57:10
【问题描述】:

下面的代码应该运行 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;

【问题讨论】:

  • perlthrtut: "想混合fork()和线程?请躺下等感觉过去。注意fork()的语义因平台而异。例如,一些Unix系统将所有当前线程复制到子进程中,而其他系统只复制调用 fork() 的线程。您已被警告!"

标签: multithreading perl fork


【解决方案1】:

在我的 Linux 机器上,使用来自 POSIX_exit 而不是 exit 有效。不过,此解决方案可能无法移植到其他平台。

链接的文档说:

请注意,在 Linux 中使用线程时,这不是退出线程的好方法,因为在 Linux 中,进程和线程是一回事(注意:虽然这是 2003 年初的情况,但正在进行的项目在 Linux 中具有更多 POSIXly 语义的线程)。如果不想从线程中返回,请分离线程。

同样,perlthrtut - Tutorial on threads in Perl

考虑混合 fork() 和线程?请躺下,等到感觉过去。请注意,fork() 的语义因平台而异。例如,一些 Unix 系统将所有当前线程复制到子进程中,而其他系统只复制调用 fork() 的线程。您已被警告!

【讨论】:

  • 谢谢!适用于 Linux 和 AIX。
猜你喜欢
  • 1970-01-01
  • 2018-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-07
  • 1970-01-01
  • 2012-06-22
  • 2018-04-08
相关资源
最近更新 更多