名前付きパイプを使用して、プロデューサー、一部のリーダー、一部のライターの 3 種類のプロセス間で通信しています。次に、すべてのプロセスを単純に実行するスクリプトを作成しました。run.sh プロセスが強制終了されるか、すべての子プロセスが終了すると、プロセスも強制終了されます。run.sh スクリプトは次のとおりです。
#!/bin/bash
MAX_WRITERS=2
MAX_READERS=2
trap 'jobs -p | xargs kill' EXIT
./producer.sh &
for ((i=1; i<=$MAX_READERS; i++)); do ./reader_one.sh & done
for ((i=1; i<=$MAX_WRITERS; i++)); do ./writer_one.sh & done
wait
スクリプトは非常に単純ですが、いくつかのプロセスが実行されているのがまだ見えるため、機能していないようです (producer.sh が強制終了されただけです)。
$ ./run.sh
... some activities ...
^C
$ ps aux | grep "[b]ash ./"
user 48909 ... /bin/bash ./writer_one.sh
user 48906 ... /bin/bash ./writer_one.sh
user 48904 ... /bin/bash ./reader_one.sh
user 48901 ... /bin/bash ./reader_one.sh
だから私はこれで殺す必要があります:
$ ps aux | grep "[b]ash ./" | awk '{print $2}' | xargs kill
どうすればそれを機能させることができますか?
更新 1:
でバックグラウンドで実行されたジョブ&
は信号に抵抗できるようです。SIGINT
そのため、シンプルkill
では役に立ちません。kill -9
またはをトラップ内で使用すると、信号を受信しますが、適切に殺されたkill -TERM
だけで、生きたままになります。producer.sh
./run.sh: line 21: 50039 Killed: 9 ./producer.sh
./run.sh: line 21: 50040 Killed: 9 ./reader_one.sh
./run.sh: line 21: 50041 Killed: 9 ./reader_one.sh
./run.sh: line 21: 50042 Killed: 9 ./writer_one.sh
./run.sh: line 21: 50043 Killed: 9 ./writer_one.sh
$ ps aux | grep "[b]ash ./"
user 50069 ... /bin/bash ./writer_one.sh
user 50068 ... /bin/bash ./writer_one.sh
user 50064 ... /bin/bash ./reader_one.sh
user 50061 ... /bin/bash ./reader_one.sh
更新 2:
名前付きパイプでデータを待っているだけですreader_one.sh
。writer_one.sh
更新 3:read_one.sh
ここに;
のコードがあります。おそらくその理由は、パイプの直前にあるため、サブシェルですwhile
init_read(){
...
}
read_one(){
...
}
init_reader
while true; do
cat to_read | while read line; do
read_one $line;
done
done