gpt4 book ai didi

multithreading - perl:在不按 “enter”的情况下不会退出

转载 作者:行者123 更新时间:2023-12-03 13:16:01 24 4
gpt4 key购买 nike

use threads;
use threads::shared;
use Term::ReadKey;

sub input_worker {

local $SIG{'KILL'} = sub { threads->exit(0); return;};

while (1) {
if (defined(my $char = ReadKey 0, *STDIN)) {
print "$char";
}
}

return;
} ## end sub input_worker

my $in_thr = threads->create(\&input_worker);
sleep 5;
my $rc = $in_thr->kill('KILL')->join();
print "$rc\n";

该程序不会自行退出,而是会挂起。
仅在按“enter”(进入)后退出

我如何做到这一点,以便在发出“杀戮”信号后自动退出

P.S.我不想使用detach();

最佳答案

混合信号和线程是一个挑战,仅因为$thread->kill实际上并不使用实际信号(因为信号发送到进程而不是线程)。也是一样,因为如果这样做,SIGKILL可能会破坏事情。

即使在谈论“正常”信号时,由于perl对它们的处理,您也会有一些意想不到的行为,请参阅: perlipc 。它不是不可能使用,但是您需要了解所涉及的警告。

但是问题的根源在于-信号得到了安全处理,这意味着perl会等到适当的时候对其进行处理。在“读取”操作期间不会执行此操作,因此信号处理将被推迟。

我认为这里发生的可能是您的ReadKey不是像您认为的那样是非阻塞操作。关于 Term::ReadKey 联机帮助页

ReadKey MODE [, Filehandle] Takes an integer argument, which can currently be one of the following values:


 0    Perform a normal read using getc
-1 Perform a non-blocked read
>0 Perform a timed read

因此,它要做的是-从 STDIN开始读取,并阻塞(忽略信号),直到您按enter键为止。此时它将运行您的信号处理程序。

鉴于您要在此处执行的操作-我建议您根本不使用信号,而是-使用共享变量。

像这样的东西:
use threads;
use threads::shared;
use Term::ReadKey;

my $done : shared;

sub input_worker {
while ( not $done ) {
if ( defined( my $char = ReadKey( -1, *STDIN ) ) ) {
print "$char";
}
}
return;
} ## end sub input_worker

my $in_thr = threads->create( \&input_worker );
sleep 10;
$done++;
my $rc = $in_thr->join();
print "$rc\n";

将在超时后终止,并且因为它正在执行非阻塞读取,所以它将按时释放,而无需输入。不过,您应该注意-该线程将快速“旋转”循环,以等待查看是否已按下输入-因此它的CPU效率不是很高。 (周期中的一小段延迟会极大地帮助那里,比如说0.1s)。

关于multithreading - perl:在不按 “enter”的情况下不会退出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30194725/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com