【发布时间】:2021-12-01 23:39:21
【问题描述】:
我正在尝试在 Perl 中异步进行输入处理(从控制台)。我的第一种方法是使用IO::Select,但这在 Windows 下不起作用。
然后我看到了Non-buffered processor in Perl 的帖子,大致暗示了这一点:
binmode STDIN;
binmode STDOUT;
STDIN->blocking(0) or warn $!;
STDOUT->autoflush(1);
while (1) {
my $buffer;
my $read_count = sysread(STDIN, $buffer, 4096);
if (not defined($read_count)) {
next;
} elsif (0 == $read_count) {
exit 0;
}
}
这对于常规 Unix 系统可以正常工作,但不适用于 Windows,sysread 实际上会阻塞。我已经在带有 64 位 Strawberry Perl 5.32.1 的 Windows 10 上进行了测试。
当您检查blocking() 的返回值(如上面的代码中所做的那样)时,结果表明调用失败并显示有趣的错误消息“尝试对非套接字的操作进行操作”。
编辑:我的应用程序是一个国际象棋引擎,理论上可以在终端中交互式运行,但通常通过管道与 GUI 进行通信。因此,Win32::Console 没有帮助。
自博文发布后发生了什么变化?作者明确声称这种方法适用于 Windows。我可以使用任何其他选项,也许是 Win32:: 命名空间中的某个模块?
【问题讨论】:
-
顺便说一句,
perldoc perlport没有提到blocking()。 -
Win32::Console,参见
$CONSOLE->InputChar(1)。不确定它是否阻塞。如果是这样,也使用$CONSOLE->GetEvents() -
还有一种快速而肮脏的方法:使用线程。线程可以使用充当管道的套接字(例如 Win32::SocketPair)与主程序通信,从而允许您在主程序中进行非阻塞读取。
-
我已经编辑了这个问题,提到
STDIN通常不是一个 tty 而是一个管道。因此Win32::Console不是一个选项。此外,当您在控制台中用鼠标选择某些内容时,甚至GetEvent也会阻塞。
标签: windows perl io nonblocking