我只是在尝试找出如何正确使用open2
函数。
请参阅下面的示例。它适用于较小的$max
,但是很自然,如果我向$hIn
写足够长的时间,那么最终它将被阻塞,因为没有东西连续读取输出上的数据。
use 5.26.0;
use IPC::Open2;
my $max = 100000;
my $pid = open2(my $hOut, my $hIn, "cat") || die "failed 'cat': $!";
{
my $cnt = 0;
#When $max is big (e.g. 100000) so the code below will get blocked
#when writing to $hIn
while ($cnt<$max) {say $hIn $cnt++;}
close($hIn) || say "can't close hIn";
}
while(<$hOut>) { print; }
close($hOut) || say "can't close hOut";
waitpid( $pid, 0 );
我能想到的唯一解决方案是启动另一个线程,该线程将在后台进行编写。
使用下面的代码,我可以根据需要向$hIn
中写入尽可能多的数据,并在主线程中读取它们,但是$hIn
似乎并没有关闭。因此,while(<$hOut>)
在等待更多输出时将永远不会结束。
use 5.26.0;
use threads;
use IPC::Open2;
my $max = 100000;
my $pid = open2(my $hOut, my $hIn, "cat") || die "failed 'cat': $!";
my $thr = threads->create(sub {
my $cnt = 0;
while ($cnt<$max) {say $hIn $cnt++;}
#The close does not have any effect here (although no error is produced)
close($hIn) || say "can't close hIn";
});
#This outputs all the data written to $hIn but never leaves the loop...
while(<$hOut> ) { print; }
close($hOut) || say "can't close hOut";
$thr->join;
waitpid( $pid, 0 );
我的问题是:
use threads
),那么有人可以提供open2的工作示例,该示例可以写入和读取大量数据,而不会有阻塞等待读者或阅读器的风险。作家?编辑:按照您的建议,这里是使用IPC :: Run的上述代码的实现:
use 5.26.0;
use IPC::Run qw/ run /;
my $max = 1000000;
run sub {
my $cnt = 0;
while ($cnt<$max) {say $cnt++;}
},
"|", "cat",
"|", sub {
while(<> ) {
print;
}
}
or die "run sub | cat | sub failed: $?";
它运行无缺陷,代码可读性强……我很高兴了解此模块。谢谢大家!
但是,我认为这个问题尚未得到解答。如果无法直接使用open2
编写此功能,那为什么还会存在并使人们感到困惑呢?同样,无法从其他线程关闭文件句柄在我看来也像是个错误(肯定是-关闭应该至少报告一个错误)。