在网上做了一些搜索,找到了使用命名管道的简单“教程”。但是当我使用后台作业时,似乎会丢失很多数据。
[[编辑:找到了一个更简单的解决方案,请看帖子的回复。因此我提出的问题现在是学术性的 - 万一有人想要一个工作服务器]]
我正在使用Ubuntu 10.04,Linux 2.6.32-25-generic #45-Ubuntu SMP Sat Oct 16 19:52:42 UTC 2010 x86_64 GNU/Linux
GNU bash,版本4.1.5(1)-release(x86_64-pc-linux-gnu)。
我的bash函数是:
function jqs
{
pipe=/tmp/__job_control_manager__
trap "rm -f $pipe; exit" EXIT SIGKILL
if [[ ! -p "$pipe" ]]; then
mkfifo "$pipe"
fi
while true
do
if read txt <"$pipe"
then
echo "$(date +'%Y'): new text is [[$txt]]"
if [[ "$txt" == 'quit' ]]
then
break
fi
fi
done
}
我在后台运行这个程序:
> jqs&
[1] 5336
现在我要把它喂:
for i in 1 2 3 4 5 6 7 8
do
(echo aaa$i > /tmp/__job_control_manager__ && echo success$i &)
done
输出结果不一致。我经常无法得到所有的成功回声。我最多只能获得与成功回声相同数量的新文本回声,有时更少。如果我将“feed”中的“&”删除,它似乎可以工作,但我会一直被阻塞直到输出被读取。因此,我希望让子进程被阻塞,但不是主进程。
目标是编写一个简单的作业控制脚本,以便我最多可以并行运行10个作业,并将其余作业排队进行后续处理,但可靠地知道它们确实在运行。
下面是完整的作业管理器:
function jq_manage
{
export __gn__="$1"
pipe=/tmp/__job_control_manager_"$__gn__"__
trap "rm -f $pipe" EXIT
trap "break" SIGKILL
if [[ ! -p "$pipe" ]]; then
mkfifo "$pipe"
fi
while true
do
date
jobs
if (($(jobs | egrep "Running.*echo '%#_Group_#%_$__gn__'" | wc -l) < $__jN__))
then
echo "Waiting for new job"
if read new_job <"$pipe"
then
echo "new job is [[$new_job]]"
if [[ "$new_job" == 'quit' ]]
then
break
fi
echo "In group $__gn__, starting job $new_job"
eval "(echo '%#_Group_#%_$__gn__' > /dev/null; $new_job) &"
fi
else
sleep 3
fi
done
}
function jq
{
# __gn__ = first parameter to this function, the job group name (the pool within which to allocate __jN__ jobs)
# __jN__ = second parameter to this function, the maximum of job numbers to run concurrently
export __gn__="$1"
shift
export __jN__="$1"
shift
export __jq__=$(jobs | egrep "Running.*echo '%#_GroupQueue_#%_$__gn__'" | wc -l)
if (($__jq__ '<' 1))
then
eval "(echo '%#_GroupQueue_#%_$__gn__' > /dev/null; jq_manage $__gn__) &"
fi
pipe=/tmp/__job_control_manager_"$__gn__"__
echo $@ >$pipe
}
调用
jq <name> <max processes> <command>
jq abc 2 sleep 20
我将启动一个进程。那部分工作正常。 启动第二个也没问题。一个一个手动启动似乎也很好。但在循环中启动10个进程似乎会失去系统,就像上面更简单的例子一样。
有什么提示可以解决这种显然的IPC数据丢失将不胜感激。
谢谢, Alain。