来自信号处理程序的pthread_join

时间:2014-06-03 21:13:07

标签: c multithreading pthreads posix

我有一个捕获程序,另外捕获数据并将其写入文件也会打印一些统计信息。打印统计信息的函数

static void* report(void)
{
         /*Print statistics*/
}
使用每秒过期的ALARM大致每秒调用

。所以程序就像

void capture_program()
{
     pthread_t report_thread;

     while (!exit_now )
     {
         if (pthread_create(&report_thread,NULL,report,NULL)) {
             fprintf(stderr,"Error creating reporting thread! \n");
         }
         /*
           Capturing code
           --------------
           --------------
         */
         if(doreport)
             usleep(5);
     }
}  

void *report(void *param)
{
     while (true)
     {
         if (doreport)
         {
             doreport = 0
             //access some register from hardware
             usleep(5)
         }
     }
 }

计时器到期时设置doreport标志。如果设置了此标志,则调用report()清除标志。我正在使用usleep在程序中的两个线程之间交替。这似乎是工作得很好。 我还有一个信号处理程序来处理SIGINT(即CTRL + C)

static void
anysig(int sig)
{
    if (sig != SIGINT)
        dagutil_set_signal_handler(SIG_DFL);

    /* Tell the main loop to exit */
    exit_now = 1;
    return;
}

我的问题:

1) Is it safe to call pthread_join from inside the signal handler?
2) Should I use exit_now flag for the report thread as well?

1 个答案:

答案 0 :(得分:4)

真的,不要这样做。

我无法找到任何建议pthread_join是异步信号安全的参考(默认情况下你应该假设它们不是)。

但即使是这种情况,你所建议做的事情也非常难看。

在信号处理程序中,只需在sig_atomic_t变量中设置一个标志即表示已发生信号。然后定期轮询,并在信号处理程序之外写入统计信息或加入线程。

如果你不喜欢投票,那么另一种巧妙的技巧就是自编写管道'。在信号处理程序写入写入结尾的位置设置一个管道(因为write是异步安全的)并在主select()循环或其他任何内容中读取。