我正在玩 bash 的 trap 功能。下面的脚本展示了某种竞争条件。
#! /bin/bash
set -x
trap sigusr1 USR1
ANCESTOR_PID=$$
function sigusr1
{
num+=1
declare -p num
}
function have_a_child
{
sleep $(echo $((1 + RANDOM % 500)) / 1000 | bc -l) &
wait $!
kill -USR1 $ANCESTOR_PID
}
declare -i i=0
declare -i num=0
while (( i < 100 )); do
have_a_child &
i+=1
done
mkfifo -m 0400 /tmp/test.sh.fifo
read < /tmp/test.sh.fifo
简而言之,我创建了 100 个子进程,它们随机休眠 0 ~ 500 毫秒,然后每个子进程向其父进程发送一个 USR1 单条消息。当他们的父母收到 USR1 信号时,它将递增编号变量 1。
如果 无竞争条件发生了,并且每个子进程发送的每个 USR1 信号都由父脚本处理依次地, 这编号变量应该是100当所有子进程终止时。但我观察到编号是随机的,就像98、93、96...
所以,我猜这里发生了一些嵌套或函数重入:当陷阱处理程序正在处理从某个子进程发送的一个 USR1 信号时,另一个子进程发送了另一个 USR1 信号,也许第三个子进程也可以同样参与......
问题:
我不确定父级何时收到多个信号,父级是否会生成多个处理程序(如多个线程),或者父级只是执行一些嵌套过程逻辑?
bash 中是否有任何机制可以用来解决这种竞争条件?