【问题标题】:Perl non-blocking user inputPerl 非阻塞用户输入
【发布时间】:2015-02-11 23:04:59
【问题描述】:
#!/usr/bin/perl -w

use Term::ReadKey;
ReadMode('cbreak');

while (1) {
    $char = ReadKey(-1);
    next unless defined $char;
    printf("Char: $char Decimal: %d\tHex: %x\n", ord($char), ord($char));
}
ReadMode('normal');

上面的效果很好。但是我希望能够在某些可执行文件运行时获得用户输入。所以我尝试了以下方法,但它不起作用。也许在尝试获取用户输入时运行可执行文件会搞砸?如果是这样,我该怎么做?

我从 $myexe 获取输出,根据用户输入,我想从 $myexe 过滤不同的东西

#!/usr/bin/perl -w

use Term::ReadKey;
my $myexe = 'bin/myexecutable';
open my $EXE,
    "$myexe distribute 2>&1 |"
    or die 'Cannot open EXE';

ReadMode('cbreak');
while (<$EXE>) {
    $char = ReadKey(-1);
    if (defined $char) {
        print ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $char\n"; #i would press a key but nothin prints out
    }
    print "$_\n";
}
ReadMode('normal');

【问题讨论】:

  • bin/myexecutable distribute 的输出是什么?
  • @g.tsh 一堆字符串。例如,“建筑 ”
  • @g.tsh 是 bin/myexecutable 的输出,让我无法获得用户输入?
  • while (&lt;$EXE&gt;) 被阻止。所以每次exe打印一行到STDOUT时都会执行循环(和ReadKey)。
  • @g.tsh 它每秒打印多行。高达每秒 100 行。所以 ReadKey 应该像 while (1) 循环一样工作

标签: perl


【解决方案1】:

我对运行像Term::ReadKey 那样的“忙-等待”循环持谨慎态度。但我的建议是——如果你想同时做两件事——可能值得考虑做一些并行代码。

类似:

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

use Term::ReadKey;


my $myexe = 'bin/myexecutable';

my $filter : shared;


sub worker {
    open my $EXE, "$myexe distribute 2>&1 |"
        or die 'Cannot open EXE';
    while ( my $line = <$EXE> ) {

        #do something with filter here;
        print "$filter : $line";
    }

}

$filter = 0;
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";
    $filter = $keypress;
}
ReadMode 0;

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

这是一些相当简单的示例代码 - 您可以通过多种方式对其进行扩展,但原则是这样的:

  • 您启动一个线程来“完成工作”。
  • 您在“主”线程中处理“按键监视”。

因为那里处于睡眠状态,所以您不必忙于等待按键(例如,轮询与处理器旋转一样快)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    • 2011-01-25
    • 2010-10-01
    相关资源
    最近更新 更多