【问题标题】:Ending thread either on completion or after specified time whichever occurs first in Perl在完成时或在指定时间之后结束线程,以 Perl 中先发生者为准
【发布时间】:2015-05-12 19:17:23
【问题描述】:

我在 Perl 线程方面遇到了一些问题,需要您的帮助。

我想在 perl 中运行一些任务 [adb 执行一些命令]。我的要求是在执行命令完成后退出循环/线程,或者在指定时间 [比如 3 小时] 后终止执行任务本身。为此,我正在尝试使用:线程

任务 1 - 将执行一些事情 - 可能需要更少或更多的时间 任务 2 - 3 小时计时器

所以它正在部分工作。我的意思是一旦 ADB 任务完成就退出循环,而不是其他方式。

<pre>
use threads;
    my $thr = threads->create(\&sub1);   # Spawn the thread
    $thr->detach();   # Now we officially don't care any more
    my $thr = threads->create(\&sub2);   # Spawn the thread
    $thr->join();   
    #sleep_string(10);        # Let thread run for awhile
    sub sub1 {
       sleep(10800); 
    }        
    sub sub2 {
       Execute ADB task
    }        
</pre>

【问题讨论】:

  • 当超时发生时,你可以给线程发送一个“线程信号”。如果您想干净地退出,您将有一个处理程序捕获该信号和die。 (这仅在操作由 Perl 代码组成时才有效,因为“线程信号”仅在 Perl 指令之间检查。)这是简单的部分。困难的部分是等待线程完成或计时器结束。
  • 必须是线程吗?因为alarm()fork() 的组合很容易做到这一点。
  • 谢谢ikegami,我会检查并告诉你
  • 谢谢Sobrique,不一定是一个线程,所以请您提供更多输入

标签: multithreading perl


【解决方案1】:

从 cmets 开始,我的建议是根本不要线程。这看起来就像你正在运行的一个简单的系统命令,并且你想在超时后终止。

所以我会这样处理:

#!/usr/bin/perl

use strict;
use warnings;

alarm 3; 
my $pid = open ( my $output_from_proc, "-|", "tail -f /var/log/messages" ); 
$SIG{'ALRM'} = sub { 
    print "Killing $pid because of timeout\n"; 
    kill 15, $pid 
    undef $SIG{'ALRM'}; #irrelevant unless you reuse alarm
};
print <$output_from_proc>; 
waitpid ( $pid, 0 ); 

open 作为可执行文件打开,并执行它自己的 fork - 并通过 $output_from_proc 返回 STDOUT。您设置了一个“ALRM”信号处理程序。 alarm 请求内核在指定时间之后向您发送SIGALRM(它非常精确,但对于超时来说已经足够了)。

当你的ALRM 信号到来时,进程被杀死。如果你真的想要,这应该在一个线程中工作,但我会尽量避免它。

【讨论】:

  • 感谢 Sobrique,一个疑问是 $output_from_proc 是否在 ALRM / 超时之前完成 - 那么它将如何退出
  • 当它执行此操作时,$output_from_proc 文件句柄将关闭,并且您在读取它时会得到一个 EOF。或者您可以通过waitpid 进行测试以查看它是否已退出 - 在收割之前它会一直保持僵尸状态
  • 抱歉回复延迟/非常感谢 Sobrique。效果很好。
猜你喜欢
  • 2021-04-29
  • 1970-01-01
  • 1970-01-01
  • 2015-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-01
  • 2020-10-22
相关资源
最近更新 更多