如何在不阻塞 Perl 的情况下测试 STDIN? [英] How can I test STDIN without blocking in Perl?

查看:68
本文介绍了如何在不阻塞 Perl 的情况下测试 STDIN?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写我的第一个 Perl 应用程序——一个与 Arduino 微控制器通信的 AOL Instant Messenger 机器人,后者反过来控制一个伺服系统,该伺服系统将按下我们系统管理员服务器上的电源按钮,该服务器每 28 小时左右随机冻结一次.

I'm writing my first Perl app -- an AOL Instant Messenger bot that talks to an Arduino microcontroller, which in turn controls a servo that will push the power button on our sysadmin's server, which freezes randomly every 28 hours or so.

我已经完成了所有困难的工作,我只是想添加最后一点代码来中断主循环并在用户键入退出"时退出 AIM.

I've gotten all the hard stuff done, I'm just trying to add one last bit of code to break the main loop and log out of AIM when the user types 'quit'.

问题是,如果我尝试在主程序循环中从 STDIN 读取,它会阻止进程直到输入输入,基本上使机器人处于非活动状态.我在阅读之前尝试过测试 EOF,但没有骰子...... EOF 总是返回 false.

The problem is, if I try to read from STDIN in the main program loop, it blocks the process until input is entered, essentially rendering the bot inactive. I've tried testing for EOF before reading, but no dice... EOF just always returns false.

以下是我正在使用的一些示例代码:

Here's below is some sample code I'm working with:

while(1) {
    $oscar->do_one_loop();

# Poll to see if any arduino data is coming in over serial port
    my $char = $port->lookfor();

# If we get data from arduino, then print it
    if ($char) {
        print "" . $char ;
    }

    # reading STDIN blocks until input is received... AAARG!
    my $a = <STDIN>;
    print $a;
    if($a eq "exit" || $a eq "quit" || $a eq 'c' || $a eq 'q') {last;}
}

print "Signing off... ";

$oscar->signoff();
print "Done\n";
print "Closing serial port... ";
$port->close() || warn "close failed";
print "Done\n";

推荐答案

Perl 内置是 select(),这是对 select() 系统调用的传递,但对于理智的人,我推荐 IO::Select.

The Perl built-in is select(), which is a pass-through to the select() system call, but for sane people I recommend IO::Select.

代码示例:

#!/usr/bin/perl

use IO::Select;

$s = IO::Select->new();
$s->add(\*STDIN);

while (++$i) {
  print "Hiya $i!\n";
  sleep(5);
  if ($s->can_read(.5)) {
    chomp($foo = <STDIN>);
    print "Got '$foo' from STDIN\n";
  }
}

这篇关于如何在不阻塞 Perl 的情况下测试 STDIN?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆