如何从主线程中唤醒一个沉睡的线程?

问题描述 投票:1回答:3

我有一个捕获程序,除了捕获数据并将其写入文件外,还打印一些统计数据。

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())?

c multithreading pthreads posix
3个回答
4
投票

当主线程的定时器响起时,如何唤醒沉睡的线程(运行report())?

我想可以用 条件变量 就是你要找的机制。 让报告线程阻塞在条件变量上,主线程在你想让报告线程唤醒的时候给条件变量发信号(更详细的说明见链接)。


6
投票

你可以用sigwait让一个线程睡觉,然后用pthread_kill给这个线程发信号让它醒来。 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);

2
投票

我在对一个UDP聊天服务器进行编码时也遇到过类似的问题:有一个线程_1,只有在报警中断(超时查看客户端是否还活着)或者另一个线程_2(这个线程满足客户端请求)信号到达时才会工作。我所做的是将这个线程_1置于睡眠状态(sleep(n*TICK_TIMER),其中TICK_TIMER为报警到期值,n为某个整数>1),并以 SIGALRM 信号。参见sleep()文档

报警处理程序(要使用这个,你必须启动它。"signal(SIGALRM, tick_handler); alarm(5);")

void tick_handler(){tick_flag++; alarm(5); }

将发送一个 SIGALRM 当超时时。

而从另一个线程_2中唤醒这个睡眠线程_1的命令是。

    pthread_kill(X,SIGALRM);

其中X是一个 pthread_t 类型。如果你的线程_1是你的主线程,你可以通过以下方式获得这个数字 pthread_t X = pthread_self();

© www.soinside.com 2019 - 2024. All rights reserved.