gpt4 book ai didi

Perl, Parallel::ForkManager - 如何为 fork 实现超时

转载 作者:行者123 更新时间:2023-12-04 10:27:44 24 4
gpt4 key购买 nike

是否可以使用 Parallel::ForkManager 为 fork 实现某种超时(时间限制)?

基本的 Parallel::ForkManager 脚本如下所示

use Parallel::ForkManager;
my $pm = Parallel::ForkManager->new( 10 );
for ( 1 .. 1000 ) {
$pm->start and next;
# some job for fork
$pm->finish;
}
$pm->wait_all_children();

我想限制“# some job for fork”的时间。例如,如果它没有在 90 秒内完成。那么它( fork )应该被杀死/终止。
我想过 using this但我不得不说,我不知道如何将它与 Parallel::ForkManager 一起使用。

编辑

谢谢霍布斯和池上。您的两个建议都有效......但仅在这个基本示例中,而不是在我的实际脚本中:(。
screenshot
这些 fork 将永远存在,而且 - 老实说 - 我不知道为什么。我使用这个脚本几个月了。没有改变任何东西(尽管很多事情取决于外部变量)。
每个分支都必须从网站下载页面,解析它并将结果保存到文件中。每个前叉的时间不应超过 30 秒。超时设置为 180 秒。那些悬挂的 fork 是完全随机的,所以很难追踪问题。这就是为什么我想出了一个临时的、简单的解决方案——超时和终止。

什么可能会在我的代码中禁用(中断)您的超时方法?我没有其他 alarm()在我的代码中的任何地方。

编辑 2

其中一个 fork 挂了 1 小时 38 分并返回了“超时 PID”——这是我输入的 die()alarm() .所以超时有效......但它迟到了大约 1h36,5m ;)。你有什么想法?

最佳答案

更新

很抱歉在结束后更新,但如果我没有指出 Parallel::ForkManager 也支持 run_on_start,那我就失职了。打回来。这可用于安装处理 time() 的“ child 注册”功能。 - 为您标记 PID。

例如。,

$pm->run_on_start(sub { my $pid = shift; $workers{$pid} = time(); });

结果是,结合 run_on_wait如下所述,P::FM 的主循环不需要做任何特别的事情。也就是说,它可以保持一个简单的 $pm->start and next ,回调将处理其他所有事情。

原答案

Parallel::ForkManager 的 run_on_wait处理程序和一些簿记,可以强制挂起和 ALRM-proof 子进程终止。

由该函数注册的回调可以定期运行,而 $pm等待 child 终止。
use strict; use warnings;
use Parallel::ForkManager;

use constant PATIENCE => 90; # seconds

our %workers;

sub dismiss_hung_workers {
while (my ($pid, $started_at) = each %workers) {
next unless time() - $started_at > PATIENCE;
kill TERM => $pid;
delete $workers{$pid};
}
}

...

sub main {
my $pm = Parallel::ForkManager->new(10);
$pm->run_on_wait(\&dismiss_hung_workers, 1); # 1 second between callback invocations

for (1 .. 1000) {
if (my $pid = $pm->start) {
$workers{$pid} = time();
next;
}
# Here we are child. Do some work.
# (Maybe install a $SIG{TERM} handler for graceful shutdown!)
...
$pm->finish;
}

$pm->wait_all_children;

}

(正如其他人所建议的,最好让 children 通过 alarm() 自我调节,但这对你来说似乎间歇性地行不通。你也可以诉诸于浪费,粗暴的黑客行为,比如让每个 child 自己 fork() or exec('bash', '-c', 'sleep 90; kill -TERM $PPID') 。)

关于Perl, Parallel::ForkManager - 如何为 fork 实现超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10971046/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com