我有一个我编写的Perl程序,它解析类似SQL的语句,并创建一个在大型机上运行的作业,该大型机根据条件提取字段和记录。记录返回到PC,然后以各种格式输出(例如csv,XML等)。我选择了SQL的INTO子句来列出文件和输出。
问题是将记录写入SQLite数据库(其中一种输出格式)需要相当长的时间,我不希望它阻止处理下一个SQL命令(如果有多个SQL查询)传入)。所以,我以为我会使用fork()来实现这一点。
原始代码是:
foreach (@into) {
dointo($_,$recs);
}
@into是一个文件和格式列表(例如'File1.csv'是发送到File1.csv的逗号分隔格式,'File1.xml'是写入File1.xml的XML格式等)到被处理。子程序dointo处理其中的每一个。 $ recs是一种迭代器,它以各种格式返回记录(flat,anonhash,anonarray等)。
所以,我把代码更改为:
foreach (@into) {
unless (fork()) {
dointo($_,$recs);
exit 0;
}
}
但现在当代码运行时,它似乎工作,但它每次都会产生运行时错误。
我没有捕获fork()的返回值,因为我真的不在乎等待forked进程完成。这可能是错误吗?父进程是否需要等待子进程完成才能安全退出?
任何帮助都将不胜感激。
(BTW,Windows XP是操作系统,Activestate Perl 5.10.0是Perl版本)
答案 0 :(得分:4)
答案 1 :(得分:0)
Windows上的Fork一直有点狡猾。请记住,fork()可以返回两个错误值:如果您在子进程中则返回0,如果fork失败则返回undef。因此,对于上面的代码,您可能会遇到一个失败的fork。此外,如果您不想等待您的孩子,我认为您应该将$ SIG {CHLD}设置为'IGNORE',以避免在您不等待的情况下创建僵尸。
有关详细信息,请参阅perlipc,perlfaq8和waitpid。另外,如果你说出运行时错误是什么会有所帮助:)
我忘了提到你可能也想看Parallel::ForkManager。它会让你更加简单。
请参阅perlfork以了解Windows上的fork仿真限制。