Perl非阻塞用户输入

时间:2015-02-11 07:47:25

标签: perl

#!/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');

1 个答案:

答案 0 :(得分: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();
}

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

  • 你开始一个'做工作'的主题。
  • 你在'主'线程中处理'按键观看'。

因为那里有一个睡眠,所以你没有忙于等待按键(例如,轮询与处理器旋转一样快)。