子プロセスにフォークしているプロセスがあります。親プロセスが存在する場合、子プロセスは存在してはなりません。
::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 に子を強制終了させる方法はありますか?