我有一个捕获程序,另外捕获数据并将其写入文件也会打印一些统计信息。打印统计信息的函数
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?
答案 0 :(得分:4)
真的,不要这样做。
我无法找到任何建议pthread_join
是异步信号安全的参考(默认情况下你应该假设它们不是)。
但即使是这种情况,你所建议做的事情也非常难看。
在信号处理程序中,只需在sig_atomic_t
变量中设置一个标志即表示已发生信号。然后定期轮询,并在信号处理程序之外写入统计信息或加入线程。
如果你不喜欢投票,那么另一种巧妙的技巧就是自编写管道'。在信号处理程序写入写入结尾的位置设置一个管道(因为write
是异步安全的)并在主select()
循环或其他任何内容中读取。