我只是想知道如何正确使用
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 );
我能想到的唯一解决方案是启动另一个线程,在后台进行写作。
通过下面的代码,我可以写入
欣欣
尽可能多的数据,并在主线程中读取它们,但是
欣欣
好像没有关门。正因为如此,
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
在Perl中是不鼓励的),那么有人能提供一个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
直接地说,为什么会存在这样的情况并使人们困惑?另外,无法关闭来自不同线程的文件句柄对我来说似乎是一个错误(当然,这是-关闭至少应该报告一个错误)。