我的 perl 脚本的一部分有问题,困扰了我好几天。总结一下,目的是分块读取一个大文件并对输入流进行一些操作(与我的问题无关)。当我第一次实现它时,我只是遍历了文件,然后在上面做了一些事情,就像这样:
while (read FILE, $buffer, $chunksize){
callSomeOperation($buffer);
# Do some other stuff
}
不幸的是,该文件非常大,并且操作在某种程度上很复杂,有许多函数调用,因此这导致内存稳步增加 perl 无法再分配内存并且脚本失败了。所以我做了一些调查并尝试了一些方法来最小化内存开销(在循环外定义变量,设置为 undef 等等),这导致分配的内存大小增加得更慢,但最后仍然失败。(如果我想得对,perl 将内存还给操作系统是……这在实践中不会发生。)
所以我决定将函数调用及其所有定义嵌套在一个子线程中,等待它的完成,加入,然后用下一个块再次调用线程:
while (read FILE, $buffer, $chunksize){
my $thr = threads->create(\&thrWorker,$buffer);
$thr->join();
}
sub thrWorker{
# Do the stuff here!
}
如果线程加入,这可能是一个解决方案!但实际上并没有。如果我用 $thr->detach(); 运行它 一切正常,除了我同时得到数百个线程,这不是一个好主意,在这种情况下,我需要连续运行它们。
所以我对这个加入问题进行了一些调查,并得到一些声音说 perl 5.16.1 可能存在问题,所以我更新到 5.16.2 但它仍然没有加入。在邮件列表中的任何地方,我不记得我读过有人设法让线程加入 CPAN 模块 Thread::Queue 但这对我也不起作用。
所以我放弃了线程并试图分叉这个东西。但是对于叉子,“叉子”的总数似乎是有限的?无论如何,直到第 13 次到第 20 次迭代都很好,然后放弃了它不能再分叉的消息。
my $pid = fork();
if( $pid == 0 ){
thrWorker($buffer);
exit 0;
}
我还尝试使用 CPAN 模块 Parallel::ForkManager 和 Proc::Fork 但这没有帮助。
所以现在我不知何故被卡住了,无法自拔。也许别人可以!任何建议都非常感谢!
- 我怎样才能让这个东西与线程或子进程一起工作?
- 或者至少我怎样才能强制 perl 释放内存,以便我可以在同一个过程中做到这一点?
关于我的系统的一些附加信息:操作系统:Windows 7 64bit / Ubuntu Server 12.10 Perl on Windows:Strawberry Perl 5.16.2 64bit
我在 Stackoverflow 上的第一篇文章。希望我做对了:-)