我已经编写了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;
}
}
}
答案 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中设置特定的处理程序)。