如何从主线程唤醒睡眠线程?

liv*_*hak 1 c multithreading posix pthreads

我有一个捕获程序,此外捕获数据并将其写入文件也打印一些统计信息.打印统计信息的功能

static void report(void)
{
         /*Print statistics*/
}
Run Code Online (Sandbox Code Playgroud)

使用每秒过期的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 

}
Run Code Online (Sandbox Code Playgroud)

计时器到期时doreport设置report()标志.如果设置了此标志,则清除该标志.

当计时器在主线程中关闭时,如何唤醒睡眠线程(运行report())?

Jer*_*ner 6

当主线程中的计时器关闭时,如何唤醒睡眠线程(运行 report())?

我认为条件变量是您正在寻找的机制。在条件变量上设置报告线程块,只要您希望报告线程唤醒,主线程就会向条件变量发出信号(有关更详细的说明,请参阅链接)。


joh*_*ash 5

您可以使用sigwait来休眠线程,然后通过pthread_kill发出该线程的信号.杀死听起来不错,但它并没有杀死线程,它会发出信号.这种方法非常快.它比条件变量快得多.我不确定它是更容易,更难,更安全或更危险,但我们需要表现所以我们走这条路.

在启动代码中的某个地方:

sigemptyset(&fSigSet);
sigaddset(&fSigSet, SIGUSR1);
sigaddset(&fSigSet, SIGSEGV);
Run Code Online (Sandbox Code Playgroud)

睡觉,线程这样做:

int nSig;
sigwait(&fSigSet, &nSig);
Run Code Online (Sandbox Code Playgroud)

醒来(从任何其他线程完成)

pthread_kill(pThread, SIGUSR1);
Run Code Online (Sandbox Code Playgroud)

或者醒来你可以这样做:

tgkill(nPid, nTid, SIGUSR1);
Run Code Online (Sandbox Code Playgroud)

我们的代码在创建子线程之前在主线程上调用它.我不确定为什么要这样做.

pthread_sigmask(SIG_BLOCK, &fSigSet, NULL);
Run Code Online (Sandbox Code Playgroud)