【发布时间】:2017-03-22 20:27:54
【问题描述】:
我有一个 perl 程序,它试图将一堆文件从一种格式转换为另一种格式(通过命令行工具)。它工作正常,但太慢了,因为它一次又一次地转换文件。
我研究并利用了 fork() 机制,试图将所有转换作为子叉子产生,希望利用 cpu/cores。
编码已经完成并经过测试,它确实提高了性能,但并没有达到我的预期。 在查看 /proc/cpuinfo 时,我有这个:
> egrep -e "core id" -e ^physical /proc/cpuinfo|xargs -l2 echo|sort -u
physical id : 0 core id : 0
physical id : 0 core id : 1
physical id : 0 core id : 2
physical id : 0 core id : 3
physical id : 1 core id : 0
physical id : 1 core id : 1
physical id : 1 core id : 2
physical id : 1 core id : 3
这意味着我有 2 个 CPU 和每个四核?如果是这样,我应该能够分出 8 个分叉,并且假设我应该能够完成 8 分钟的工作(每个文件 1 分钟,8 个文件)以在 1 分钟内完成(8 个分叉,每个分叉 1 个文件)。
但是,当我测试运行它时,仍然需要 4 分钟才能完成。它似乎只使用了 2 个 CPU,但没有使用内核?
因此,我的问题是:
perl 的 fork() 是否仅基于 CPU 而不是内核并行它?或者也许我没有做对?我只是使用 fork() 和 wait()。没什么特别的。
我假设 perl 的 fork() 应该使用内核,我可以编写一个简单的 bash/perl 来证明我的操作系统(即 RedHat 4)还是 Perl 不是这种症状的罪魁祸首?
添加:
我什至尝试多次运行以下命令来模拟多次处理和监控 htop。
while true; do echo abc >>devnull; done &
不知何故 htop 告诉我我有 16 个内核?然后当我生成 4 个上述 while 循环时,我看到其中 4 个每个使用 ~100% cpu。当我产生更多时,它们都开始均匀地降低 CPU 利用率。 (例如 8 个处理,参见 htop 中的 8 个 bash,但每个使用 ~50%)这是否意味着什么?
先谢谢了。我尝试了谷歌但无法找到明显的答案。
编辑:2016-11-09
这里是 perl 代码的摘录。我很想看看我在这里做错了什么。
my $maxForks = 50;
my $forks = 0;
while(<CIFLIST>) {
extractPDFByCIF($cifNumFromIndex, $acctTypeFromIndex, $startDate, $endDate);
}
for (1 .. $forks) {
my $pid = wait();
print "Child fork exited. PID=$pid\n";
}
sub extractPDFByCIF {
# doing SQL constructing to for the $stmt to do a DB query
$stmt->execute();
while ($stmt->fetch()) {
# fork the copy/afp2web process into child process
if ($forks >= $maxForks) {
my $pid = wait();
print "PARENTFORK: Child fork exited. PID=$pid\n";
$forks--;
}
my $pid = fork;
if (not defined $pid) {
warn "PARENTFORK: Could not fork. Do it sequentially with parent thread\n";
}
if ($pid) {
$forks++;
print "PARENTFORK: Spawned child fork number $forks. PID=$pid\n";
}else {
print "CHILDFORK: Processing child fork. PID=$$\n";
# prevent child fork to destroy dbh from parent thread
$dbh->{InactiveDestroy} = 1;
undef $dbh;
# perform the conversion as usual
if($fileName =~ m/.afp/){
system("file-conversion -parameter-list");
} elsif($fileName =~ m/.pdf/) {
system("cp $from-file $to-file");
} else {
print ERRORLOG "Problem happened here\r\n";
}
exit;
}
# end forking
$stmt->finish();
close(INDEX);
}
【问题讨论】:
-
Perl 只使用
fork系统调用。您应该在 C 中看到完全相同的行为。 -
不看代码很难调试。
-
您的代码可能有问题;展示它,我们可以提供帮助。
-
节目有点晚了,但是由于您有代码而我没有看到它,所以我想我会更新答案。总结是 - 我猜“文件转换”是磁盘 io 限制,而不是 CPU 限制。
cp当然是。
标签: multithreading perl fork