Parallel::ForkManager 分叉后只有一个活动线程,为什么?

4

在使用Parallel::Fork进行分叉后,我只得到了一个工作线程:

ps -ef | grep ./BuildReportIndexV_VR2.pl

503      15955  9531 18 13:11 pts/0    00:02:06 /usr/bin/perl ./BuildReportIndexV_VR2.pl promt_tenant=AD backward=1
503      16102 15955 99 13:13 pts/0    00:09:29 /usr/bin/perl ./BuildReportIndexV_VR2.pl promt_tenant=AD backward=1
503      16103 15955  0 13:13 pts/0    00:00:02 /usr/bin/perl ./BuildReportIndexV_VR2.pl promt_tenant=AD backward=1
503      16104 15955  0 13:13 pts/0    00:00:02 /usr/bin/perl ./BuildReportIndexV_VR2.pl promt_tenant=AD backward=1
503      16105 15955  0 13:13 pts/0    00:00:03 /usr/bin/perl ./BuildReportIndexV_VR2.pl promt_tenant=AD backward=1

15955进程是父进程,16102及以下是子进程。

以下是相关代码:

my $pm = Parallel::ForkManager->new($MAX_PROCESSES);
$pm->set_max_procs( $MAX_PROCESSES );

my $start_index;
my $last_index;

for ( $start_index = 0,
      $last_index=$start_index+$subhash_size-1;

      $last_index <= keys %$index_hr;

      $start_index=$last_index+1, $last_index=$start_index+$subhash_size-1
    )
{
    $pm->start and next;
    create_report_subprocess( $index_hr, $start_index, $last_index );
    $pm->finish;
}
$pm->wait_all_children;

print "After all children are waited: last index: $last_index\n";
if ( $last_index > keys %$index_hr) {
    $last_index = keys %$index_hr;
    create_report_subprocess( $index_hr, $start_index, $last_index );
} 

我将$MAX_PROCESSES设置为4。

我期望所有4个线程都在运行。为什么只有一个?


这些是进程,而不是线程。因此其中有3个没有使用CPU;可能它们正在等待某些东西。你知道它们在等待什么吗? - ysth
它们与正在运行的进程相同,没有区别。问题是:为什么只有4个等效线程中的一个占用了整个CPU? - rlib
仅仅是计算,没有任何数据库或文件交互吗? - ysth
我无法复制这个; 将create_report_subprocess()调用替换为($x += $_) -= $_ for 1..100000000;,我得到所有进程报告99%的cpu(有4个可用核心),在一个单核vm中,它们各自报告24%的cpu。如果你尝试一下,你会看到什么? - ysth
好的,实际上父级与Postgres数据库之间存在连接。在任何子级中都没有访问数据库。 这可能是原因吗?无法检查建议的替换:现在无法访问服务器;我稍后会尝试。 - rlib
显示剩余3条评论
1个回答

0

在你的 for 循环之前,尝试为任何活动的数据库或语句句柄设置 AutoInactiveDestroy


没有帮助,但问题确实在于数据库连接。在父进程中关闭DBI连接后,所有子进程在所有CPU上运行。我应该如何处理这种情况? - rlib
@rlib - 阅读有关DBI分叉的文档 - 实际上,没有实用的方法可以在不同进程之间共享单个DB连接。 - Richard Huxton
我怀疑您可能错过了一个活跃的句柄。请确保您的DBD::Pg版本支持AutoInactiveDestroy,并尝试打开https://metacpan.org/pod/DBI#TRACING以查看子进程实际在做什么。 - ysth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接