2012-02-10 2 views
2

私はプロセスを持っており、プロセスが終了したときにプロセスを再開したい。これを達成するために、私はprctl(PR_SET_PDEATHSIG, SIGHUP);を使用してその親の殺害を捕捉し、それを再び開始する、子「保護者」プロセスを開始する。ここでSIGHUPで殺されたプロセスを再起動

は、保護者のコードは、(省略ロギング)である:

void restart (int signal) { 
    if (getppid() == 1) { 
     if (fork() == 0) { 
      execl("./process", 0); 
     } 
     exit(1); 
    } 
} 

int main() { 
    prctl(PR_SET_PDEATHSIG, SIGHUP, NULL, NULL, NULL); 

    struct sigaction new_action, old_action; 
    new_action.sa_handler = restart; 
    sigemptyset (&new_action.sa_mask); 
    new_action.sa_flags = 0; 

    sigaction (SIGHUP, NULL, &old_action); 

    if (old_action.sa_handler != SIG_IGN) { 
     sigaction (SIGHUP, &new_action, NULL); 
    } 

    while (getppid() != 1) { 
     sleep(86400000); 
    } 
    return 0; 
} 

と親:

int main() { 
    if (fork() == 0) { 
     execl("./guardian", 0); 
    } 
    while (1) { 
     cout << "I am process\n"; 
     sleep(1); 
    } 
    return 0; 
} 

私が持っている問題はそれだけで一度に動作することです。よさそうだ

USER  PID %CPU %MEM VSZ RSS TTY  STAT START TIME COMMAND 
1012  13058 0.0 0.3 20244 1932 pts/1 Ss 08:22 0:00 -sh 
1012  22084 0.0 0.1 11484 1004 pts/1 S+ 11:20 0:00 \_ ./process 
1012  22085 0.0 0.1 11484 1000 pts/1 S+ 11:20 0:00  \_ [guardian] 
1012  12510 0.0 0.3 20784 1712 pts/0 Ss 08:14 0:00 -sh 
1012  22088 0.0 0.1 17412 1012 pts/0 R+ 11:20 0:00 \_ ps fu 

:ここではプロセスが最初に開始されたps出力されます。次に、kill -9 22084でプロセスを終了します。そして再びps出力:

USER  PID %CPU %MEM VSZ RSS TTY  STAT START TIME COMMAND 
1012  13058 0.0 0.3 20244 1932 pts/1 Ss+ 08:22 0:00 -sh 
1012  12510 0.0 0.3 20784 1712 pts/0 Ss 08:14 0:00 -sh 
1012  22091 0.0 0.1 17412 1012 pts/0 R+ 11:21 0:00 \_ ps fu 
1012  22089 0.0 0.1 11484 996 pts/1 S 11:20 0:00 [process] 
1012  22090 0.0 0.1 11484 996 pts/1 S 11:20 0:00 \_ [guardian] 

と私はプロセスを強制終了時に再びkill -9 22089保護者がSIGHUPコールバックを取得していないようです(私は彼らがここでは省略され、ログから確認)。

USER  PID %CPU %MEM VSZ RSS TTY  STAT START TIME COMMAND 
1012  13058 0.0 0.3 20244 1932 pts/1 Ss+ 08:22 0:00 -sh 
1012  12510 0.0 0.3 20784 1712 pts/0 Rs 08:14 0:00 -sh 
1012  22339 0.0 0.1 17412 1008 pts/0 R+ 11:27 0:00 \_ ps fu 
1012  22090 0.0 0.1 11484 996 pts/1 S 11:20 0:00 [guardian] 

私の質問は、なぜ保護者がSIGHUPを取得しないのですか?

バックグラウンドプロセスグループと何か関係があると思われます。プロセスを再起動するとバックグラウンドグループになります(ps statのS +とSを比較してください)。

+0

これは非常識です。子供が親を再起動させるのではなく、親だけで子を再起動させるのはなぜですか?システム全体がセットアップされているので、それは簡単です。 –

+0

これはあまり意味がないことは分かっています。私は私のAndroidアプリケーションにあるプロセスの再起動ロジックを再現しています。 Androidはapp(親プロセス)を起動し、そのプロセスは親の状態を監視するguardian(子プロセス)を起動します。 – lstipakov

+0

@WilliamPursell:そうですね。私のアンチウィルスソフトウェアは明らかに非常に似たようなことをしています。アンチウイルスプログラムを強制終了することは、標準的なハッカー手法であるため、ウイルス対策プログラムは複数のインスタンスを作成し、それぞれが死亡した親を監視するガーディアンを作成します。 Kill -9はブロックされず、検出できません。子プロセスで検出可能です。 –

答えて

4

SIGHUPのシグナルハンドラ処理中にSIGHUPがブロックされているようです。 fork()exec()はシグナルマスクを継承しているため、第2のガーディアンはそれを再び受信しません。

ブロック解除を解除するSIGHUPfork()の後のシグナルハンドラでは、exec()の親の前にブロックします。

+2

sigset_t x; sigemptyset(&x); sigaddset(&x、SIGHUP); sigprocmask(SIG_UNBLOCK、&x、NULL); – lstipakov

+0

ニートワンライナー!) –

関連する問題