等待进程从睡眠状态恢复

等待进程从睡眠状态恢复

script.sh是由run.sh 次并行。为了N=1script.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

如果脚本本身需要相当长的时间来运行,这将无法解决您所写的要求,但除非您可以将睡眠与处理分开,否则我不相信它完全有可能实现您的要求并仍然满足您规定的标准。

相关内容