我有一個分叉到子進程的進程。如果父進程存在,子進程不應該存在。所以,我在子進程中調用:: prctl(PR_SET_PDEATHSIG,SIGKILL)來殺死父進程。最後發生的是父線程調用pthread_exit,並且該線程最終成爲殺死子進程的催化劑。在父線程退出時調用prctl(PR_SET_PDEATHSIG,SIGNAL),而不是父進程退出
這裏是我的代碼:
parent.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
孩子死了。如果你在孩子身上取出prctl電話,它不會失效。
在http://www.kernel.org/doc/man-pages/online/pages/man2/prctl.2.html prctl頁面似乎描述此調用應在父進程死亡時,調用SIGKILL,而不是父線程。當父進程死亡而不是父線程時,有沒有辦法讓prctl殺死子進程?
恐怕看起來問題並不在於線程過早死亡。我是故意這樣做的。因此,孩子睡6秒,而父母線只睡1秒。 我試圖做的一點是父進程睡6秒,而孩子也睡6秒。然而,孩子只有1(當分叉的線程死亡,但父進程仍在繼續時)失效。 有沒有什麼辦法可以讓prctl在父進程的時候死掉,而不是分叉死的線程? – user1418199
我並不完全確定,但我很確定,當線程正在休眠時,它完全暫停。也就是說,沒有任何短於SEGFAULT類型的錯誤會導致它調用'pthread_exit'。我會仔細檢查POSIX線程文檔。 – Codeman
嗯,好吧,看起來如果你運行代碼,孩子在睡覺時因prctl調用而失效(這是本文的重點)。我不想讓孩子在分叉的線程死亡時停止使用。父母過程死後,我想讓孩子失靈。 – user1418199