如何用IPC::Open2过滤大量数据?
我的任务是使用外部实用程序(addr2line)从 perl 脚本中过滤一些数据。数据量相当大。我需要将大量数据打印到程序的 stdin 并读回大量数据(从程序的 stdout 读回我的脚本)。
现在我使用 IPC::Open2
执行此操作,但我不混合读取和写入。这合法吗? Open2
会在管道中缓冲任意大小的数据吗?
我的代码:
my $cmd="addr2line -e $prog_name ";
use IPC::Open2;
local (*Reader, *Writer);
my $pid = open2(\*Reader, \*Writer, $cmd);
for(@requests) { # this array is HUGE, 100s of thousands of entries
print Writer "$_\n";
}
close Writer;
for(@requests) {
$function_name = <Reader>;
$filesource = <Reader>;
#... store ..
}
close Reader;
waitpid($pid,0);
My task is to filter some data from perl script with external utility (the addr2line). The data size is quite large. I need to print a lot of data to stdin
of program and read a lot of data back (from stdout
of program into my script).
Now I do this with IPC::Open2
, but I don't mix reading and writing. Is this legal? Will Open2
buffer any size of data in pipe?
My code:
my $cmd="addr2line -e $prog_name ";
use IPC::Open2;
local (*Reader, *Writer);
my $pid = open2(\*Reader, \*Writer, $cmd);
for(@requests) { # this array is HUGE, 100s of thousands of entries
print Writer "$_\n";
}
close Writer;
for(@requests) {
$function_name = <Reader>;
$filesource = <Reader>;
#... store ..
}
close Reader;
waitpid($pid,0);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,您的程序编写方式会遇到缓冲区容量限制。您的输入缓冲区 (
Reader
) 将填满并阻止外部程序的执行。混合读取和写入会有所帮助,因为您清空输入缓冲区的速度与外部程序填充输入缓冲区的速度大致相同。
另一件有用的事情是使用文件进行进程间通信,而不是管道或套接字(如 IPC::Open2 所做的那样)。那么您将仅受可用磁盘空间量的限制。你可以自己做,不过
Forks::Super
默认情况下使用 IPC 文件。Yes, you will run into buffer capacity constraints the way your program is written. Your input buffer (
Reader
) will fill up and block execution of your external program.Mixing reading and writing would help, as you would be emptying the input buffer at about the same rate that the external program is filling it.
Another thing that would help is using files for interprocess communication instead of pipes or sockets (as
IPC::Open2
does). Then you would be limited only by the amount of free disk space. You could do it yourself, thoughForks::Super
uses files for IPC by default.管道的尺寸有限。您的方法将陷入僵局
一种可能的解决方案:
或者, IPC::Run 具有以下工具:也会让这变得容易。
unixy 的方法是使用 IO::Select ,但这确实很痛苦。
Pipes have limited sizes. Your approach will deadlock
One possible solution:
Alternatively, IPC::Run has tools that will make this easy too.
The unixy way would be to use IO::Select, but that's a real pain.