我有一个捕获程序,另外捕获数据并将其写入文件也会打印一些统计信息。打印统计信息的函数
static void report(void)
{
/*Print statistics*/
}
使用每秒过期的ALARM大致每秒调用。所以程序就像
void capture_program()
{
pthread_t report_thread
while()
{
if(pthread_create(&report_thread,NULL,report,NULL)){
fprintf(stderr,"Error creating reporting thread! \n");
}
/*
Capturing code
--------------
--------------
*/
if(doreport)
/*wakeup the sleeping thread.*/
}
}
void *report(void *param)
{
//access some register from hardware
//sleep for a second
}
计时器到期时设置doreport
标志。如果设置了此标志,则调用report()
清除标志。
当计时器在主线程中关闭时,如何唤醒睡眠线程(运行report())?
答案 0 :(得分:5)
您可以使用sigwait来休眠线程,然后通过pthread_kill发出该线程的信号。杀死听起来不错,但它并没有杀死线程,它会发出信号。这种方法非常快。它比条件变量快得多。我不确定它是否更容易,更难,更安全或更危险,但我们需要性能,所以我们走这条路。
在某处的启动代码中:
sigemptyset(&fSigSet);
sigaddset(&fSigSet, SIGUSR1);
sigaddset(&fSigSet, SIGSEGV);
要睡觉,线程会这样做:
int nSig;
sigwait(&fSigSet, &nSig);
唤醒(从任何其他线程完成)
pthread_kill(pThread, SIGUSR1);
或者醒来你可以这样做:
tgkill(nPid, nTid, SIGUSR1);
我们的代码在创建子线程之前在主线程上调用它。我不确定为什么要这样做。
pthread_sigmask(SIG_BLOCK, &fSigSet, NULL);
答案 1 :(得分:4)
如何唤醒睡眠线程(运行报告()) 计时器在主线程中关闭?
我认为condition variable是您正在寻找的机制。在条件变量上有报告线程块,并且只要您希望报告线程被唤醒,主线程就会发出条件变量(请参阅链接以获取更详细的说明)。
答案 2 :(得分:3)
在对UDP聊天服务器进行编码时,我遇到了类似的问题:有一个线程_1仅在警报中断(超时以查看客户端是否仍然存在)或另一个线程_2(此线程满足客户端请求)到达时才起作用。我所做的就是让该线程_1进入睡眠状态(sleep(n*TICK_TIMER)
,其中TICK_TIMER是警报到期值,n是大于1的整数),然后用SIGALRM
信号唤醒该线程。 See sleep() doc
警报处理程序(要使用它,您必须将其初始化:“ signal(SIGALRM,tick_handler); alarm(5);“)
void tick_handler(){tick_flag++; alarm(5); }
在发生超时时将发送SIGALRM
。
从另一个线程_2唤醒此睡眠线程_1的命令是:
pthread_kill(X,SIGALRM);
其中X是pthread_t
类型。如果您的thread_1是您的主线程,则可以通过pthread_t X = pthread_self();