我有一个程序正在调用另一个程序并处理孩子的输出,即:
my $pid = open($handle, "$commandPath $options |");
现在我尝试了几种不同的方式从句柄中读取而没有阻塞,但很少或没有成功。
我发现了相关的问题:
但是他们遇到了这些问题:
ioctl
一直崩溃perl sysread
阻塞0字节(常见)我不确定如何解决这个问题。
答案 0 :(得分:4)
管道在Windows上不像在Unix-y系统上那样功能。你不能在它们上使用4参数select
,默认容量微乎其微。
最好尝试基于套接字或文件的解决方法。
$pid = fork();
if (defined($pid) && $pid == 0) {
exit system("$commandPath $options > $someTemporaryFile");
}
open($handle, "<$someTemporaryFile");
现在你需要处理更多的蠕虫 - 定期运行waitpid
来检查后台进程何时停止创建输出,在你读取之后调用seek $handle,0,1
来清除eof条件$handle
,清理临时文件,但是有效。
我已经编写了Forks::Super
模块来处理这样的问题(和许多其他问题)。对于这个问题,你可以像
use Forks::Super;
my $pid = fork { cmd => "$commandPath $options", child_fh => "out" };
my $job = Forks::Super::Job::get($pid);
while (!$job->is_complete) {
@someInputToProcess = $job->read_stdout();
... process input ...
... optional sleep here so you don't consume CPU waiting for input ...
}
waitpid $pid, 0;
@theLastInputToProcess = $job->read_stdout();