好的,我在所有演示中都运行POV-Ray,但 POV 仍然是单线程的,不会使用多个内核。因此,我开始考虑 BASH 中的解决方案。
我编写了一个通用函数,它接受命令列表并在指定数量的子 shell 中运行它们。这实际上可行,但我不喜欢它以线程安全 的多进程方式处理访问下一个命令的方式:
- 它需要一个带有命令的文件(每行 1 个)作为参数,
- 要获得“下一个”命令,每个进程(“线程”)将:
- 等到它可以创建一个锁定文件,使用:ln $CMDFILE $LOCKFILE
- 从文件中读取命令,
- 通过删除第一行修改 $CMDFILE,
- 删除 $LOCKFILE。
有没有更清洁的方法来做到这一点? 我无法让子外壳正确地从 FIFO 中读取一行。
顺便说一句,这样做的目的是增强我在 BASH 命令行上的功能,而不是寻找非 bash 解决方案。我倾向于从命令行执行很多复杂的任务,并且想要工具箱中的另一个工具。
同时,这是处理从文件中获取下一行的函数。如您所见,它每次读取/删除一行时都会修改一个磁盘文件。这看起来有点骇人听闻,但我没有想出更好的方法,因为 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"
}