主线程被杀后为什么子线程活着?

时间:2016-08-03 08:46:21

标签: c linux multithreading pthreads signals

我编写了一个代码,我从父线程创建了两个子线程。

然后,当从那些子线程内的另一个终端接收到信号时,我打印了threadID并退出了线程。

我有两个问题。

  1. 我收到来自子线程的信号。为什么要打印父线程的threadID

  2. 杀死父线程后,子线程如何活着?

  3. 守则:

    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行是3 threadID。第一个是主threadID,然后是两个辅助线程。

    然后从以下代码块打印threadID

    if (signo == 1){
        printf("%d\n", pthread_self());
        pthread_exit(NULL);
    }
    

    为什么会发生这种情况?

2 个答案:

答案 0 :(得分:3)

信号将传递到进程,而不是传递给单个线程。所以,你不能只为一个线程拥有一个信号处理程序,就像你在这里做的那样。 您可以做的是使用pthread_sigmask()阻止您感兴趣的信号,并让专用线程使用sigwait()处理信号,这是最常用的方式。

答案 1 :(得分:0)

此外,您只能从信号处理程序中安全地调用异步信号安全函数。来自https://msdn.microsoft.com/en-us/library/system.data.datarow.isnull.aspx

  

异步信号安全功能

     

自处理以来,信号处理函数必须非常小心   其他地方可能会在执行中的某个任意点中断   该计划。 POSIX具有“安全功能”的概念。如果一个   signal中断执行不安全的函数,以及 handler   要么调用不安全的函数,要么处理程序通过调用终止   siglongjmp()printf(),程序随后调用   不安全的函数,那么程序的行为是不确定的。

链接的手册页有一个可以安全地从信号处理程序中调用的函数列表。如果该功能不在该列表中,则称其不安全。没有例外。

请注意,pthread_exit()pthread_exit()都不在异步信号安全功能列表中。

从信号处理程序中调用$fields_string = ''; $fields = array( 'v' => 1, 'tid' => "UA-xxxxxx-1", 'cid' => $userid, 't' => 'transaction', 'ti' => $transaction_id, 'tr' => $Transaction_revenue, 'ts' => $Transaction_shipping, 'tt' => $tax, 'cu' =>'EUR' ); 会产生其他几个问题:

  • 退出的主题通常不受任何控制。在许多情况下,信号可以传递给任何线程。

  • 退出线程可以使对象处于未知状态 - 例如,互斥锁可以被不再存在的线程锁定。

  • 还将从信号处理程序上下文中调用任何线程清理处理程序the Linux signal man page