script.sh
是由run.sh
氮次并行。为了N=1,script.sh
进程设置为在实际启动前休眠 30-45 秒。
我如何订购所有script.sh
实例N>1 不开始直到第一个(N=1)script.sh
睡醒了?进程之间不能直接通信。
我想告诉其他进程,第一个进程仍在睡眠,他们必须等待,他们已经初始化,但他们无法执行他们的代码。
进程之间也无法直接通信
答案1
如果你事先知道N,你可以使用fifo作为信号量。
mkfifo sem;
exec 3<>sem
rm -f sem
然后让每个 N>1 进程从中读取一个字节&3
。由于这些字节最初不可用,因此也会使它们进入睡眠状态。
一旦 N==1 完成休眠,它就可以将 N 个字节写入 &3,唤醒每个一直在等待 &3 字节的进程。
#!/bin/bash -e
mkfifo p
exec 3<>p
rm p
main()(
echo $FUNCNAME beg
sleep 2 &>/dev/null
printf '\n\n\n' >&3
echo $FUNCNAME end
)
worker()(
echo $FUNCNAME$1 beg
read -n 1 <&3
echo $FUNCNAME$1 end
)
main &
worker 1 &
worker 2 &
worker 3 &
wait
输出:
main beg
worker1 beg
worker2 beg
worker3 beg
main end
worker2 end
worker3 end
worker1 end
另一种方法可能是使用信号。如果您可以确保您的脚本作为终端作业运行$$
(父 shell pid)是相应进程组的进程组 id,那么您可以让您的工作人员无限期地休眠(理想情况下是调用该pause
函数的进程;或者sleep $hugevalue
如果您不能做前者),在此之前,让他们建立一个处理程序,例如 SIGUSR1。主进程第一个工作者应该忽略该信号。然后,第一个工人可以通过 向所有其他工人发出信号kill -SIGUSR1 -$$
,这将杀死无限期休眠者,使工人继续。
#!/bin/bash
trap ' ' SIGUSR1
main()(
trap - SIGUSR1
echo $FUNCNAME beg
sleep 2 &>/dev/null
echo $FUNCNAME end
kill -s SIGUSR1 -$$
)
worker()(
trap ' ' SIGUSR1
echo $FUNCNAME$1 beg
sleep 10000000000 &>/dev/null
echo $FUNCNAME$1 end
)
main &
worker 1 &
worker 2 &
worker 3 &
wait
输出:
main beg
worker2 beg
worker1 beg
worker3 beg
main end
User defined signal 1
worker1 end
User defined signal 1
worker3 end
User defined signal 1
[1] 31554 user-defined signal 1 ./scr1
(我不知道如何关闭"user-defined signal 1"
消息)
答案2
如果没有看到您的代码片段,我只能猜测它可能是这样的:
for k in $(seq $N)
do
script.sh &
done
因此,为了等待第一个完成然后再解雇其他人,您可以执行以下操作:
for k in $(seq $N)
do
script.sh &
[[ $k == 1 ]] && wait
done
如果脚本本身需要相当长的时间来运行,这将无法解决您所写的要求,但除非您可以将睡眠与处理分开,否则我不相信它完全有可能实现您的要求并仍然满足您规定的标准。