BCo*_*tes 13 xargs split parallelism
我有一个任务来处理 stdin 上的文件列表。程序的启动时间很长,每个文件所用的时间差异很大。我想生成大量这样的进程,然后将工作分派给不忙的进程。有几种不同的命令行工具几乎可以满足我的要求,我将其缩小到两个几乎可以工作的选项:
find . -type f | split -n r/24 -u --filter="myjob"
find . -type f | parallel --pipe -u -l 1 myjob
Run Code Online (Sandbox Code Playgroud)
问题是split做一个纯循环,所以其中一个进程落后又落后,延迟了整个操作的完成;虽然parallel想要每 N 行或每字节输入产生一个进程,但我最终在启动开销上花费了太多时间。
是否有类似的东西可以将流程和馈送线重用于已解锁标准输入的任何流程?
我不这么认为。在我最喜欢的杂志上有一篇关于 bash 编程的文章,它满足了你的要求。我愿意相信,如果有工具可以做到这一点,他们会提到它们。所以你想要一些类似的东西:
set -m # enable job control
max_processes=8
concurrent_processes=0
child_has_ended() { concurrent_processes=$((concurrent_processes - 1)) }
trap child_has_ended SIGCHLD # that's magic calling our bash function when a child processes ends
for i in $(find . -type f)
do
# don't do anything while there are max_processes running
while [ ${concurrent_processes} -ge ${max_processes}]; do sleep 0.5; done
# increase the counter
concurrent_processes=$((concurrent_processes + 1))
# start a child process to actually deal with one file
/path/to/script/to/handle/one/file $i &
done
Run Code Online (Sandbox Code Playgroud)
显然,您可以根据自己的喜好更改对实际工作脚本的调用。我提到的杂志最初做了诸如设置管道和实际启动工作线程之类的事情。检查一下mkfifo,但该路线要复杂得多,因为工作进程需要向主进程发出信号,表明它们已准备好接收更多数据。因此,每个工作进程需要一个 fifo 来向其发送数据,主进程需要一个 fifo 来从工作进程接收数据。
免责声明 这个脚本是我凭空写出来的。它可能存在一些语法问题。