比方说,我有一个64核服务器,我需要计算md5sum
中所有文件的/mnt/data
,并将结果存储在一个文本文件中:
find /mnt/data -type f -exec md5sum {} \; > md5.txt
上述命令的问题是,在任何给定时间只运行一个进程。我想利用我的64核的全部功能。理想情况下,我想确保在任何给定时间,64个并行md5
进程正在运行(但不超过64个)。
另外。我需要将所有进程的输出存储到一个文件中。
注意:我不是在寻找一种并行计算一个文件md5sum
的方法。我正在寻找一种方法来并行计算64个不同文件的64 md5sums,只要有来自find
的文件。
答案 0 :(得分:19)
使用GNU parallel
。您可以找到更多关于如何实现它的示例here。
find /mnt/data -type f | parallel -j 64 md5sum > md5.txt
答案 1 :(得分:8)
你也可以使用xargs,它可能比某些发行版上的并行更多。
-P控制产生的进程数。
find /mnt/data -type f | xargs -L1 -P24 md5sum > /tmp/result.txt
答案 2 :(得分:6)
如果您想要实验,请尝试安装md5deep
。 (http://md5deep.sourceforge.net)
Here is the manual您可以在这里阅读:
-jnn控制多线程。默认情况下,程序将创建一个生产者线程来扫描文件系统,每个CPU创建一个散列线程 核心。多线程导致输出文件名在 非确定性顺序,因为需要更长时间才能进行散列的文件 在他们被散列时延迟了。如果需要确定性订单, 指定-j0以禁用多线程
如果这没有帮助,则会产生I / O瓶颈。
答案 3 :(得分:1)
<强>已更新强>
如果您不想使用其他软件包,可以尝试使用以下方法:
#!/usr/bin/bash
max=5;
cpid=()
# Enable job control to receive SIGCHLD
set -m
remove() {
for i in ${!cpid[*]}; do
[ ! -d /proc/$i ] && echo UNSET $i && unset cpid[$i] && break
done
}
trap remove SIGCHLD
for x in $(find ./ -type f -name '*.sh'); do
some_long_process $x&
cpid[$!]="$x";
while [ ${#cpid[*]} -ge $max ]; do
echo DO SOMETHING && sleep 1;
done
done
wait
如果子进程退出,它首先允许接收SIGCHLD。如果SIGCHLD找到第一个不存在的进程并从cpid
数组中删除。
在for循环中,异步启动max
个some_long_process
个进程。它max
到达它会轮询添加到cpid
数组的所有pid。它等待cpid
的长度小于max
,并异步启动更多进程。
如果列表结束,则等待所有孩子完成。
<强> ADDED 强>