假设父进程产生了几个子进程,这些进程在某些时候自行停止(尚未终止)。我希望父母wait
为其所有孩子停止,这样他们就可以一步一步地工作。
这可能是一个XY问题,所以如果有更好的方法,我会全神贯注。 :)
我想为冲突构建一个协作git mergetool。
我有一个父进程,它为每个冲突文件生成一个子进程。我遗失的那篇文章是“等待所有孩子被阻止”。我怎么能这样做?
#parent.sh
# For each file in conflicting state
for f in `git ls-files --unmerged | cut -f2 | sort -u`
do
git mergetool --tool=collaborate --no-prompt "$f" &
done
# Wait for all children to be STOPPED
wait # WSTOPPED? Not sure how to do this.
echo "All files uploaded. Visit www.example.com/abc123 to collaborate."
read -rsp $'Press enter to apply changes.\n'
# Continue all child processes.
kill -SIGCONT childpids? Need a list...
wait
echo "Finished!"
子进程必须以锁步方式工作。
#collaborate-mergetool.sh
BASE=$1
LOCAL=$2
REMOTE=$3
MERGED=$4
# TODO curl POST files to server
# When the four files are uploaded:
# STOP this process and wait for siblings.
kill -SIGSTOP $$
# Download patch from server
# TODO curl GET "$filename".patch from server
# TODO apply patch
答案 0 :(得分:0)
试试这个:
# instead of using wait, poll all child processes and detect those in a stopped state
while true ; do
sleep 1
N_CHILDREN=`jobs | wc -l`
N_STOPPED=`jobs -s | wc -l`
[ $N_CHILDREN == $N_STOPPED ] && break
done
使用shell sleep,您只能以一秒的粒度进行轮询。
如果您还有其他不想等待的子流程,则需要获得更多创意并解析内置作业的输出:
STOPPED_JOBS_PIDS=`jobs -sl | awk '{print $2}'`
# Compare to my list, etc...
在某些情况下,这可能会干扰shell本身的操作。
在这种情况下,您可能需要轮询ps的输出:
...
# Get the 'stat' column and look for a T, filter by my child processes of interest
git mergetool ... & PID1=$!
git mergetool ... & PID2=$! # etc
...
while ...
N_CHILDREN=2 # number of processes
N_STOPPED=`ps -o pid -o stat -p PID1 $PID2 | tail -n +2 | awk '{print $2}' | grep T | wc -l`
...
此处,STAT列指示进程是在运行(R),休眠(S)还是停止(T)或僵尸或其他状态。