如何暂停和恢复多线程perl脚本?

时间:2014-07-31 06:10:57

标签: multithreading perl

我已经编写了perl脚本来暂停和恢复。当用户输入 Ctrl + c 时,它必须暂停并按下 c 它应该恢复。但是没有按预期正常工作。任何人都可以帮我解决这个错误:

use strict;
use threads;
use threads::shared;
use Thread::Suspend;
use Lens;


$SIG{'INT'} = 'Pause';
#$| = 1;


print chr(7);
my $nthreads = 64;
my @thrs;


for(1..$nthreads)
{
   print "START $_ \n";
   my ($thr) =  threads->create(\&worker, $_);
   push @thrs ,$thr;
}
$_->join for @thrs;
exit;

sub worker
{
   my $id = shift;
   my $tmp;
    my  $lens = Lens->new("172.16.1.65:2000");
    die "cannot create object" unless defined $lens;
    die "cannot connect to XRay at " unless defined $lens->open("172.16.1.65:2000");
   for(1..100000)
   { 
      print "Thread $id \n";

   }
   print "$id>LOAD EXIT\n";
}

sub Pause 
{
   sleep(1);
   print "\nCaught ^C\n";
   print "Press \"c\" to continue, \"e\" to exit: ";
   $_->suspend() for @thrs;
   while (1) 
   {
      my $input = lc(getc());
      chomp ($input);
      if ($input eq 'c') {
      #clock($hour,$min,$sec);
      $_->resume() for @thrs;
      return;
   }
   elsif ($input eq 'e') {
      exit 1;
   }
  }

}

1 个答案:

答案 0 :(得分:0)

嗯,你还没有具体说明它是如何做不正常的"。但我建议使用Thread::Semaphore来暂停'暂停'机制。

我还建议不要使用signal,而是执行以下操作:

#!/usr/bin/perl
use strict;
use warnings;
use threads;
use Thread::Semaphore;

use Term::ReadKey;

my $nthreads = 64;

my $thread_semaphore = Thread::Semaphore->new($nthreads);


sub worker {

    for ( 1 .. 10 ) {
        $thread_semaphore->down();
        print threads->self->tid(), "\n";

        sleep 1;
        $thread_semaphore->up();
    }
}

for ( 1 .. $nthreads ) {
    threads->create( \&worker );
}

my $keypress;
ReadMode 4;

while ( threads->list(threads::running) ) {
    while ( not defined( $keypress = ReadKey(-1) )
        and threads->list(threads::running) )
    {
        print "Waiting\nRunning:". threads->list(threads::running) . "\n";
        sleep 1;
    }
    print "Got $keypress\n";
    if ( $keypress eq "p" ) {
        print "Pausing...";
        $thread_semaphore -> down_force($nthreads);
        print "All paused\n";
    }
    if ( $keypress eq "c" ) {
        print "Resuming...";
        $thread_semaphore -> up ( $nthreads ); 
    }
}
ReadMode 0;

foreach my $thr ( threads->list ) {
    $thr->join();
}

它暂停'暂停'通过将信号量设置为零(或负数)并依赖线程检查它们是否应该在此处停止。

我认为问题的根源可能是信号传播 - 您的信号处理程序在您的线程中是全局的。您可能会发现为您的线程分别配置$SIG{'INT'} 将产生更好的结果。 (例如,在代码开头将信号处理程序设置为' IGNORE'并在生成线程后在线程/ main中设置特定的处理程序)。