C 为什么主线程被杀死后子线程仍然活着?
我已经编写了一段代码,其中我从父线程创建了两个子线程 然后,从这些子线程内的另一个终端接收到信号后,我打印C 为什么主线程被杀死后子线程仍然活着?,c,linux,multithreading,pthreads,signals,C,Linux,Multithreading,Pthreads,Signals,我已经编写了一段代码,其中我从父线程创建了两个子线程 然后,从这些子线程内的另一个终端接收到信号后,我打印threadID,并退出线程 我有两个问题 我正在接收来自子线程的信号。为什么要打印父线程的threadID 杀死父线程后,子线程如何能够存活 守则: void sig_handler(int signo) { if (signo == 1){ printf("%d\n", pthread_self()); pthread_exit(NULL);
threadID
,并退出线程
我有两个问题
threadID
void sig_handler(int signo)
{
if (signo == 1){
printf("%d\n", pthread_self());
pthread_exit(NULL);
}
}
void* doSomeThing(void* arg)
{
printf("In function -> %d\n", pthread_self());
if (signal(1, sig_handler) == SIG_ERR)
printf("\ncan't catch SIGHUP\n");
while(1)
sleep(1);
return NULL;
}
int main(int argc, char *argv[])
{
printf("In function -> %d\n", pthread_self());
char *ch1;
pthread_t tid1, tid2;
ch1 = "random";
int ret1, ret2;
ret1 = pthread_create(&tid1, NULL, &doSomeThing, (void *) ch1 );
ret2 = pthread_create(&tid2, NULL, &doSomeThing, (void *) ch1 );
while(1)
sleep(1);
return 0;
}
以下是终端中给出的输出图像:
前3行是3threadID
s。第一个是主threadID
s,然后是两个次线程
然后从以下代码块打印threadID
s
if (signo == 1){
printf("%d\n", pthread_self());
pthread_exit(NULL);
}
为什么会发生这种情况?信号被传递到进程,而不是单个线程。因此,您不能像这里所做的那样为一个线程使用一个信号处理程序。
您可以做的是阻止您感兴趣的信号并让专用线程处理使用的信号,这是最常见的方法。此外,您只能从信号处理程序中安全地调用异步信号安全函数。发件人: 异步信号安全功能 信号处理函数必须非常小心,因为 在执行过程中的某个任意点,其他位置可能会被中断 是节目的一部分。POSIX具有“安全功能”的概念。如果 信号中断不安全函数的执行,处理程序 调用不安全函数或处理程序通过调用
longjmp()
或siglongjmp()
程序随后调用
不安全函数,则程序的行为未定义
链接的手册页有一个函数列表,可以从信号处理程序中安全调用这些函数。如果该函数不在该列表中,则调用它是不安全的。没有例外
请注意,异步信号安全函数列表中既没有printf()
也没有pthread_exit()
从信号处理程序中调用pthread\u exit()
会产生其他几个问题:
- 退出的线程通常不受任何控制。在许多情况下,信号可以传送到任何线程
- 退出的线程可能使对象处于未知状态—例如,互斥锁可能被不再存在的线程锁定
- 任何线程清理处理程序也将从信号处理程序上下文中调用
信号
实际上不适用于线程。这是否意味着pthread\u self()
函数没有给出正确的线程ID
??当它在接收到信号后被调用时,@JishnuBanerjeepthread_self()
将给出调用线程的线程id。但真正的问题是不可能有每线程信号处理程序;信号处理是全过程的。请参阅链接手册页中有关如何阻止信号的示例。C标准说:“在多线程程序中使用此函数[signal
]会导致未定义的行为。”这里如何准确地调用sig_handler()?我的意思是每次调用sig_handler()时,OP都会获得不同的threadID,即OP发送信号。这个特定的程序实际上是如何管理/处理这些信号的?OP发送的信号不是特定于线程的。这是全过程的。因此,您无法确定/知道信号发送到哪个线程pthreads(7)
说:“POSIX.1区分了定向到整个进程的信号和定向到单个线程的信号的概念。根据POSIX.1,定向到进程的信号(例如,sentusing kill(2))应该由进程中任意选择的单个线程来处理。”“任意信号传递”意味着任何线程都可以接收信号并调用信号处理程序并打印其threadID。