2013-01-31 132 views
3

我是Perl新手,在处理^ C脚本时遇到问题。当我在休眠期间收到^ C后试图继续执行脚本时,我只在$ FLAG = 2之前输出;并没有什么后:代替多线程Perl脚本中的控制+ C处理

# perl test.pl 
sleeping... 
^Cawaiking... = 
# 

# perl test.pl 
sleeping... 
awaiking... ====            
some.. 
# 

它的接缝^ C是杀害进步党条线程,它死没有行动,但打印可以在主线程中执行后。有谁能帮我解决这个问题吗?

$SIG{INT} = 'IGNORE'; 
our $FLAG : shared = 1; 
... 
sub call1{ 
    $FLAG = 1; 
    my $pBar = threads->new(\&progressBarInit); 
    $pBar->detach; 
    print "sleeping...\n"; 
    sleep 5; 
    print "awaiking...\n"; 
    $FLAG = 2; 
    print "some..\n"; 
    return @result; 
} 

call1(); 

sub progressBarInit{ 
my $max = 50; 
    my $counter = 1; 
    while($FLAG == 1){ 
     progressBar($counter, $max, 50, '='); 
     $counter++; 
     if($counter > $max){$counter=1;} 
     sleep 1; 
    } 
} 

sub progressBar { 
    my ($counter, $max, $width, $char) = @_; 
    local $| = 1; 
    printf "    %-${width}s\r", $char x (($width-1)*$counter/$max); 
} 
+0

此代码在Windows上工作正常。任何'^ C'被忽略。 – 2013-01-31 13:44:23

+0

也许[这些警告](http://www.perlmonks.org/index.pl?node_id=718)可能会有所帮助,在'progressBar'中使用'syswrite'而不是'printf'? –

+0

@ ring0,但信号处理程序不调用progressBar。我不明白它会如何应用。 – 2013-01-31 13:51:38

回答

0

我认为这个问题是你设置父信号处理程序。

根据此:http://perldoc.perl.org/threads.html

信号处理程序需要在线程他们有望在采取行动的信号进行设置。下面是取消线程的例子:

使用标志,你可以使用信号来传达相反的:

sub progressBarInit { 
    # Thread 'cancellation' signal handler 
    $SIG{'KILL'} = sub { threads->exit(); }; 
    $SIG{INT} = 'IGNORE'; 
    ... 
} 
... 
# Signal the thread to terminate, and then detach 
# it so that it will get cleaned up automatically 
    my $pBar = threads->new(\&progressBarInit);  
    print "sleeping...\n"; 
    sleep 5; 
    print "awaiking...\n"; 
    $pBar->kill('KILL')->detach(); 
+0

不幸的是,它并没有帮助。如果我放置$ SIG {INT} ='IGNORE';进入progressBarInit而不是脚本的开始,它只是在^ C被按下时终止它。 (您提到的所有更改都已应用)。 –