Multithreading 如何杀死正在运行的线程并使perl应用程序保持活动状态?

Multithreading 如何杀死正在运行的线程并使perl应用程序保持活动状态?,multithreading,perl,Multithreading,Perl,在perl脚本中使用async处理线程,我需要执行一些并行功能,但是我必须为这些线程设置一个固定的时间限制(例如,最长5秒)。我需要杀死所有正在运行的线程,如果它们运行的时间更长,但仍然保持程序的活动状态。我的代码是: use threads ( 'yield', 'exit' => 'threads_only', 'stack_size' => 2*16384 ); use threads::shared; use Time:

perl脚本中使用
async
处理线程,我需要执行一些并行功能,但是我必须为这些线程设置一个固定的时间限制(例如,最长5秒)。我需要杀死所有正在运行的线程,如果它们运行的时间更长,但仍然保持程序的活动状态。我的代码是:

use threads ( 'yield',
              'exit' => 'threads_only',
              'stack_size' => 2*16384 );
use threads::shared;
use Time::HiRes qw/sleep/;

...

$start = [Time::HiRes::gettimeofday()];
my $running :shared = 0;
foreach ($entry) {
  async(
    sub {
           local $SIG{KILL} = sub { threads->exit };
           { lock $running; ++$running };

           ...

           { lock $running; --$running };
        },
  $_)->detach;
}

while ($running) {
  sleep 0.005;
  last if (Time::HiRes::tv_interval($start) > 5);
}

if ($running) {
  my @running = threads->list(threads::running);
  foreach (@running) {
    $_->kill('KILL')->detach;
  }
}

print "I am still alive\n";

有什么更好的方法可以杀死正在运行的线程并使应用程序保持活动状态吗?

不要这样做。对线程进行编码,以便它们只执行您希望完成的工作,并在没有工作可供它们执行时终止它们自己。不要试图从外面进去杀死他们。这永远不会奏效。

async返回一个线程对象,您可以在该对象上调用kill。把他们推到一个阵列上,然后杀死他们


一个更好的设计可能是让线程在这段时间后自杀。

当然有更好的方法来跟踪5秒的时间,而不是忙于等待。但是你至少在啃死一个内核,除了检查时间什么都不做。这是昂贵的热量和电力。我发表此评论是希望其他比我更了解Perl的人会注意到我的评论,并就如何用更高效的代码替换它给出建议——如果他们直接回答您的问题,他们可能会错过这一点。@sarnold-我理解,但到目前为止,其他人都声称等待是错误的,没有人提出替代方案。如果需要等待,您还可以做什么?线程在按时完成任务后会自动终止。从主程序检查超时的优点是,无论出于何种原因,线程挂起,它都将被终止。如果线程检查它的超时,我不能确定它是否总是终止。除此之外,您认为保持自己的线程数组不受异步返回的影响,而不使用
threads->list(threads::running)
的优点是什么?@stackoverflow:使用运行线程列表是一个糟糕的模型,因为它会丢失有关线程正在执行的操作的信息,强制您在一个集中的位置跟踪代码创建的每个线程及其正在执行的操作,这剥夺了您为线程分配工作的灵活性。专注于线程是一种不好的心态,会导致非常糟糕的代码——专注于需要完成的工作,并将线程视为一种工具。把线程想象成工人在房子上工作——你想管理房子的建造,而不是工人。@stackoverflow:如果线程的代码被破坏,请修复它。不要试图从外部修复它,而是修复损坏的代码本身。如果不希望线程无限期阻塞,请不要将其编码为无限期阻塞。一个进程中的所有线程都必须协作。@stackoverflow:不是线程无限期地阻塞,而是调用函数等待另一方。如果不希望线程无限期地等待,为什么要编写线程无限期地等待的代码?这就是迫使你说服它从外部停止的原因。首先,不要将其编码为无限期等待,然后就不需要从外部说服它。@stackoverflow如果不希望作业永远运行,请将作业本身编码为不永远运行。从外面偷偷摸摸是很糟糕的,会让你陷入一个笨拙的设计中。(例如,想象一下,如果HTTP代码的后续设计使用了一个帮助线程,或者在没有关联线程的情况下异步延迟作业一段时间。)@stackoverflow:您正在编写那些线程正在运行的代码。对它们进行编码以执行您想执行的操作,对它们进行编码以在不再需要它们时终止。那你就不需要杀了他们了。不是线程太慢,而是工作时间太长。当问题是工作时,您关注的是线程。@stackoverflow,它可能会释放一些资源,但我怀疑它会释放所有资源--我特别怀疑它会释放锁--并且它会使进程处于不稳定的状态。如果要执行某些终止操作,则应该使用进程,而不是线程。@stackoverflow:线程可能已分配内存,终止线程不会给它释放内存的机会。线程可能已经打开了一个文件描述符,杀死该线程就没有机会关闭它。杀死一根线简直是白痴。如果您甚至觉得自己有点想做,那么老实说,这强烈表明您根本不了解线程。一个进程是一组相互协作的线程——杀死一个线程就像杀死你自己。如果您需要一个竞争性/独立的模型,请使用进程,而不是线程。@stackoverflow:不,这可能会起作用,但仍然很糟糕。首先不要将线程编码为无限期阻塞,这样就不需要从外部向它发送信号。@stackoverflow:不,我从来没有这样做过,这也没有任何意义。我可能想停止处理某个特定的作业,但这将是作业上的一个操作,我不会将其视为线程操作。