好的,我在所有演示中都运行POV-Ray,但POV仍然是单线程的,并且不会使用多个核心。所以,我开始考虑BASH的解决方案。
我写了一个通用函数,它接受一个命令列表并在指定数量的子shell中运行它们。这实际上有效,但我不喜欢它以线程安全 多进程方式处理访问下一个命令的方式:
有更简洁的方法吗?我无法让子shell正确读取FIFO中的单行。
<小时/> 顺便提一下,的重点是增强我在BASH命令行上可以做的事情,而不是找到非bash解决方案。我倾向于从命令行执行许多复杂的任务,并希望工具箱中有另一个工具。
同时,这是处理从文件中获取下一行的函数。如您所见,它每次读取/删除一行时都会修改磁盘文件。这似乎是hackish,但我没有想出更好的东西,因为FIFO不能用bash中的 setvbuf()工作。
#
# Get/remove the first line from FILE, using LOCK as a semaphore (with
# short sleep for collisions). Returns the text on standard output,
# returns zero on success, non-zero when file is empty.
#
parallel__nextLine()
{
local line rest file=$1 lock=$2
# Wait for lock...
until ln "${file}" "${lock}" 2>/dev/null
do sleep 1
[ -s "${file}" ] || return $?
done
# Open, read one "line" save "rest" back to the file:
exec 3<"$file"
read line <&3 ; rest=$(cat<&3)
exec 3<&-
# After last line, make sure file is empty:
( [ -z "$rest" ] || echo "$rest" ) > "${file}"
# Remove lock and 'return' the line read:
rm -f "${lock}"
[ -n "$line" ] && echo "$line"
}
答案 0 :(得分:7)
#adjust these as required
args_per_proc=1 #1 is fine for long running tasks
procs_in_parallel=4
xargs -n$args_per_proc -P$procs_in_parallel povray < list
注意即将发布的coreutils nproc
命令将自动确定
可用处理单元的数量,然后可以传递给-P
答案 1 :(得分:2)
如果您需要真正的线程安全性,我建议您迁移到更好的脚本系统。
例如,使用python,您可以使用信号量/队列创建具有安全同步的真实线程。
答案 2 :(得分:2)
#!/bin/bash
pids=()
thread() {
local this
while [ ${#} -gt 6 ]; do
this=${1}
wait "$this"
shift
done
pids=($1 $2 $3 $4 $5 $6)
}
for i in 1 2 3 4 5 6 7 8 9 10
do
sleep 5 &
pids=( ${pids[@]-} $(echo $!) )
thread ${pids[@]}
done
for pid in ${pids[@]}
do
wait "$pid"
done
它似乎非常适合我正在做的事情(一次处理并行上传一堆文件)并防止它破坏我的服务器,同时仍然确保所有文件在完成脚本之前上传
答案 3 :(得分:0)
我相信你实际上是在这里分配流程,而不是线程化。我建议您使用其他脚本语言(例如perl
,python
或ruby
)寻找线程支持。