6

子プロセスにフォークしているプロセスがあります。親プロセスが存在する場合、子プロセスは存在してはなりません。

::prctl(PR_SET_PDEATHSIG, SIGKILL)そのため、親プロセスが終了した場合に子プロセスを呼び出して、それを強制終了します。

最終的に何が起こるかは、親スレッドの呼び出しpthread_exitであり、そのスレッドは子プロセスを強制終了する触媒になります。

これが私のコードです:

親.cpp:

#include <sys/prctl.h>
#include <signal.h>
#include <unistd.h>
#include <pthread.h>
#include <iostream>

void* run(void* ptr) {

    std::cout << "thread:" << getpid() << ":" << std::hex << pthread_self() << ":" << std::dec << getppid() << std::endl;
    auto pid = fork();
    if ( pid != 0 ) {
        sleep(1);
    }
    else {
        char* arg = NULL;
        execv("./child", &arg);
    }
    return NULL;
}

int main() {

    std::cout << "main:" << getpid() << ":" << std::hex << pthread_self() << ":" << std::dec << getppid() << std::endl;

    pthread_t threadid;
    pthread_attr_t attr;

    ::pthread_attr_init( &attr );
    ::pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
    ::pthread_create(&threadid,&attr,run,NULL);

    sleep(6);

    return 0;
}

child.cpp:

#include <sys/prctl.h>
#include <signal.h>
#include <unistd.h>
#include <iostream>

int main() {
    std::cout << "child:" << getpid() << ":" << std::hex << pthread_self() << ":" << std::dec << getppid() << std::endl;
    ::prctl( PR_SET_PDEATHSIG, SIGKILL );
    sleep(6);


    return 0;
}

コマンドラインで次を実行します。

$ ./parent

同時に、次のコマンドを実行して子のステータスを確認します。

$ for i in {1..10000}; do ps aux | grep child ; sleep .5; done

子供が行方不明になります。child で prctl 呼び出しを実行しても、機能しなくなりません。

prctlのman ページSIGKILLには、親スレッドではなく、親プロセスが終了したときにこの呼び出しを呼び出す必要があることが記載されているようです。

親スレッドの代わりに親プロセスが終了したときに、prctl に子を強制終了させる方法はありますか?

4

1 に答える 1

6

PR_SET_PDEATHSIG親スレッドが終了するとシグナルを受信するため、子プロセスは終了します。つまり、それを作成したスレッドが終了したときにシグナルを受け取るということです。したがって、子を親プロセスに依存させたい場合(「メイン」関数が終了したときを意味すると思います)、親プロセスの実行のメインスレッドからフォークします。Linux prctl(2)の man ページで man ページを調べると、このプロセスを作成したのはスレッドであり、呼び出し側 (この場合は子) プロセスにシグナルを配信することが具体的に述べられています。

警告: この場合の「親」は、このプロセスを作成したスレッドと見なされ ます。pthread_exit(3)つまり、親プロセスのすべてのスレッドが終了した後ではなく、そのスレッドが終了したときに (たとえば、 を介して) シグナルが送信され ます。

結論:親プロセスの実行に依存させたい場合は、実行のメインスレッドからフォークします。簡単に言えば、子プロセスをフォークするスレッドを作成せず、メイン スレッドからフォークするだけです。

于 2015-11-07T00:27:23.633 に答える