24

可以说,我有一个 64 核服务器,我需要计算md5sum中的所有文件/mnt/data,并将结果存储在文本文件中:

find /mnt/data -type f -exec md5sum {} \; > md5.txt

上述命令的问题是,在任何给定时间只有一个进程运行。我想利用我的 64 核的全部功能。理想情况下,我想确保在任何给定时间,64 个并行md5进程正在运行(但不超过 64 个)。

还。我需要将所有进程的输出存储到一个文件中。

注意:我不是在寻找一种md5sum并行计算一个文件的方法。我正在寻找一种方法来并行计算 64 个不同文件的 64 md5sums,只要有任何文件来自find.

4

4 回答 4

28

使用GNU parallel. 您可以在此处找到更多关于如何实现它的示例。

find /mnt/data -type f | parallel -j 64 md5sum > md5.txt
于 2013-05-27T11:45:22.110 回答
11

您也可以使用 xargs,它可能比某些发行版上的并行更可用。

-P 控制产生的进程数。

find /mnt/data -type f | xargs -L1 -P24  md5sum > /tmp/result.txt
于 2014-04-02T20:49:40.250 回答
7

如果您想进行实验,请尝试安装md5deep. ( http://md5deep.sourceforge.net )

这是您可以阅读的手册:

-jnn 控制多线程。默认情况下,程序将创建一个生产者线程来扫描文件系统,并为每个 CPU 内核创建一个哈希线程。多线程导致输出文件名的顺序不确定,因为需要较长时间进行哈希处理的文件在哈希处理时会延迟。如果需要确定性顺序,请指定 -j0 以禁用多线程

如果这没有帮助,则说明您遇到了 I/O 瓶颈。

于 2013-05-27T13:49:54.760 回答
1

更新

如果你不想使用额外的包你可以尝试 sg 像这样:

#!/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异步启动更多进程。

如果列表结束,则等待所有孩子完成。

添加

最后我在这里找到了一个合适的解决方案。

于 2013-05-27T12:44:06.397 回答