使用IO :: Async和矢量化STDIN

时间:2014-03-24 08:04:29

标签: multithreading perl io

我有一个多线程程序,在主线程中它等待来自STDIN的输入(永远)

use strict;
use warnings;
use feature 'say';

use IO::Async::Timer::Periodic;
use IO::Async::Loop;
use IO::Async::Handle;


my ($rin, $rout) = ('', '');
vec ($rin, fileno(STDIN), 1) = 1;

my $loop = IO::Async::Loop->new;
my $handle = IO::Async::Handle->new(
    handle => $rin,

    on_read_ready  => sub {
        say 'Ready read';
    },
);

$loop->add( $handle );
$loop->run;

在切换到IO :: Async之前,我在select上使用内置$rin调用,这样就可以了。

现在模块抱怨$rin,错误为Expected that read_handle can ->fileno at wait.pl line 20.

那么,我应该传递什么?或者是否有更好的其他线程实现?

P.S内置的perl线程模块不断崩溃,我无法使用

2 个答案:

答案 0 :(得分:4)

句柄应该是文件句柄而不是矢量,例如使用\*STDIN(并阅读清楚描述此内容的文档)。 IO :: Async与线程完全相反,例如它是一个事件驱动的模型,具有非阻塞I / O(与perl线程相比,它可以更好地扩展,更确切地说)。还有其他几个像这样的人,AnyEvent和POE可能是最受欢迎的。

答案 1 :(得分:2)

创建IO::Async::Handle时,构造函数的handle参数必须是IO对象,或响应fileno方法的内容。如果您想使用STDIN,您可以执行类似

的操作
my $handle = IO::Async::Handle->new(handle => *STDIN{IO}, on_read_ready => sub { … });

这里真正的问题是你要用vec做些什么。 vec函数是一种将字符串视为非常类似C的内存的方法。它有以下签名:

vec $string, $offset, $bits

$string的内容视为大小为$bits的元素数组,您正在访问$offset条目。由于STDIN的fileno为零,因此您将该字符串$rin中的第一位设置为1。更简单的方法是使用pack

$rin = pack "b", 1;

偶然与$rin = chr 1$rin = "\x01"相同。这样的字符串不能用作对象,数字或文件句柄。