如何从主线程唤醒睡眠线程?
我有一个捕获程序,此外捕获数据并将其写入文件还打印一些统计信息。打印统计信息的function
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())?
当计时器在主线程中关闭时,如何唤醒睡眠线程(运行report())?
我认为条件变量是您正在寻找的机制。 在条件变量上有报告线程块,并且只要您希望报告线程被唤醒,主线程就会发出条件变量信号(有关详细说明,请参阅链接)。
您可以使用sigwait来hibernate线程,然后通过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);