2

私は現在、Bash スクリプトと特にプロセス管理に関する詳細を読んでいます。「PID と親」のセクションで、次のステートメントを見つけました。

プロセスの PID は、プロセスが終了した後、親プロセスが PID が終了したかどうかを確認して終了コードを取得するまで待機するまで、使用のために解放されることはありません。

したがって、これを正しく理解していれば、bash スクリプトでプロセスを開始すると、プロセスが終了し、PID を他のプロセスで使用できなくなります。これは、他のサブプロセスを繰り返し開始するがそれらを待機しない長時間実行スクリプトがある場合、使用された PID がシステムに返されないため、最終的にリソース リークが発生することを意味しませんか? ?

wait本当はもう一方のプロセスの場合はどうでしょうか、 waitget はトラップによってキャンセルされます。これで何とか PID が解放されますか、それともトラップが捕捉された後、もう一度待つ必要がありますか?

4

2 に答える 2

2

幸いなことに、そうはなりません。正確な理由はわかりませんが、簡単にテストできます。次のスクリプトを実行します (で終了しますCtrl+C)。

#!/bin/bash

while true; do
    sleep 5 &
    sleep 1
done

6 秒以上経ってもゾンビ(漏れた PID) が発生していないことがわかります。いくつかのゾンビを見るには、次の python コードを使用します (ここでも で停止しますCtrl+C)。

#!/usr/bin/python
import subprocess, time

pl = []
while True:
    pl.append(subprocess.Popen(["sleep", "5"]))
    time.sleep(1)

6 秒後、1 つのゾンビが表示されます。

ps xaw | grep 'sleep'
...
26470 pts/2    Z+     0:00 [sleep] <defunct>
...

私の推測では、組み込みの wait コマンドの有無にかかわらず、 bash は待機し、ゾンビ プロセスを取得する結果を保存します。Python スクリプトの場合、このpl.append部分を削除すると、ガベージ コレクションによってオブジェクトが解放され、再び魔法のようにゾンビが刈り取られます。参考までに、子供がゾンビになることはありません(ウィキペディア、ゾンビプロセスから):

...親が (デフォルトで単にシグナルを無視するのではなく) SIG_IGN にハンドラーを設定することによって明示的に SIGCHLD を無視するか、SA_NOCLDWAIT フラグが設定されている場合、すべての子終了ステータス情報は破棄され、ゾンビプロセスは残されません。

于 2012-06-15T01:20:34.650 に答える
0

スクリプトが実行されているシェルがフォアグラウンド プロセスを待機するため、フォアグラウンド プロセスを明示的に待機する必要はありません。次のプロセスは、前のプロセスが終了するまで開始されません。

実行時間の長いバックグラウンドプロセスを多数開始する場合、利用可能なすべての PID を使用できますが、ulimit -uこれには制限 (無制限の可能性があります) が適用されます。

于 2012-06-15T02:13:17.973 に答える