6

子プロセスを生成し、一定時間実行し、終了していない場合は強制終了する関数を作成しようとしています。

int sysExecTimeout(const char * exePath, int timeoutSec);

この関数では、 and を使用forkexeclて子をスポーンし、タイムアウトになったら and を使用kill(pid, SIGTERM)kill(pid, SIGKILL)て 2 秒後に子が確実に終了するようにします。

pid_t pid = fork();

if(pid == 0) {
    execl("/bin/sh", "sh", "-c", exePath);
    exit(127);
} else if(pid != -1) {
    // timeout code
    if(timeout) {
        kill(pid, SIGTERM);
        sleep(2);
        kill(pid, SIGKILL);
    }
}

私は Linux を使用していますが、親プロセスが終了しても、子プロセスは自動的に強制終了されないようです。の子プロセスであるため、2 つのkill呼び出しは単に/bin/shプロセスを強制終了し、exePathコマンドを実行したままにし/bin/shます。

sysExecTimeoutをルートとするプロセス ツリー全体を強制終了するような関数を作成しようとしています。PID はpidどこにありますかpidpid = fork()

exePathコマンドが他のコマンドを生成するため、これが必要です。これは、スタックしてリソースを消費する可能性のある他のコマンドも生成する可能性があります。

実行されるバイナリ/スクリプトを制御exePathできないため、独自の親が死ぬので子供を殺すロジックをそれらに書くことはできません。

を使用してみkill(0, SIGTERM)ましたが、これはほとんど仕事をしましたが、自分のプロセスも強制終了しました:)

プロセスツリー全体がそのプログラムから開始されるように、Cでプログラムでオンにできるフラグがあるかどうか疑問に思っています。死ぬ(PID / PPIDチェーンをたどることができると仮定)。

ここでそのフラグを使用できます:

if(pid == 0) {
    turnOnRecursiveDeathFlag();

    system(exePath);
    //execl("/bin/sh", "sh", "-c", exePath);
    exit(127);
}

それを行う方法はありますか?私はしばらく探していましたが、私が見つけることができるのは、を使用したハックps -ef、または実行中の子プロセスの変更などです.

4

1 に答える 1

15

子で setpgid を使用して、その GPID を自身の PID と等しくなるように設定します。次に、親は kill(-pid,...) してグループ全体に通知できます。

pid_t pid = fork();

if(pid == 0) {
    setpgid(0, 0);
    execl("/bin/sh", "sh", "-c", exePath);
    exit(127);
} else if(pid == -1) {
    // timeout code
    if(timeout) {
        kill(-pid, SIGTERM);
        sleep(2);
        kill(-pid, SIGKILL);
    }
}

それはそれを行う必要があります。

もう 1 つ、シェルを生成するときは、ジョブ制御が有効になっていないことを確認してください。それ以外の場合は、独自のプロセス グループが作成されます。「/bin/sh -c」は問題ありません。

于 2013-03-28T21:35:46.797 に答える