我有一个多线程程序,在主线程中它等待来自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线程模块不断崩溃,我无法使用
答案 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"
相同。这样的字符串不能用作对象,数字或文件句柄。