简体   繁体   English

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

[英]How to wake up a sleeping thread from the main Thread?

I have a capture program which in addition do capturing data and writing it into a file also prints some statistics.The function that prints the statistics我有一个捕获程序,它除了捕获数据并将其写入文件还打印一些统计信息。打印统计信息的函数

static void report(void)
{
         /*Print statistics*/
}

is called roughly every second using an ALARM that expires every second.So The program is like使用每秒到期的 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 

}

The expiry of the timer sets the doreport flag.If this flag is set report() is called which clears the flag.计时器到期设置doreport标志。如果设置了该标志,则调用report()清除该标志。

How do I wake up the sleeping thread (that runs the report()) when the timer goes off in the main thread?当主线程中的计时器关闭时,如何唤醒睡眠线程(运行 report())?

You can sleep a thread using sigwait, and then signal that thread to wake up with pthread_kill.您可以使用 sigwait 使线程休眠,然后用 pthread_kill 通知该线程唤醒。 Kill sounds bad, but it doesn't kill the thread, it sends a signal. Kill 听起来很糟糕,但它不会杀死线程,它会发送一个信号。 This method is very fast.这种方法非常快。 It was much faster than condition variables.它比条件变量快得多。 I am not sure it is easier, harder, safer or more dangerous, but we needed the performance so we went this route.我不确定它是更容易、更难、更安全还是更危险,但我们需要性能,所以我们走这条路。

in startup code somewhere:在某处的启动代码中:

sigemptyset(&fSigSet);
sigaddset(&fSigSet, SIGUSR1);
sigaddset(&fSigSet, SIGSEGV);

to sleep, the thread does this:睡觉,线程这样做:

int nSig;
sigwait(&fSigSet, &nSig);

to wake up (done from any other thread)唤醒(从任何其他线程完成)

pthread_kill(pThread, SIGUSR1);

or to wake up you could do this:或者醒来你可以这样做:

tgkill(nPid, nTid, SIGUSR1);

Our code calls this on the main thread before creating child threads.我们的代码在创建子线程之前在主线程上调用它。 I'm not sure why this would be required.我不确定为什么需要这样做。

pthread_sigmask(SIG_BLOCK, &fSigSet, NULL);

How do I wake up the sleeping thread (that runs the report()) when the timer goes off in the main thread?当主线程中的计时器关闭时,如何唤醒睡眠线程(运行 report())?

I think a condition variable is the mechanism you are looking for.我认为条件变量是您正在寻找的机制。 Have the report-thread block on the condition variable, and the main thread signal the condition variable whenever you want the report-thread to wake up (see the link for more detailed instructions).在条件变量上设置报告线程块,只要您希望报告线程唤醒,主线程就会向条件变量发出信号(有关更详细的说明,请参阅链接)。

I had a similar issue when coding an UDP chat server: there is a thread_1 that only works when an alarm interruption (timeout to see if the client is still alive) OR another thread_2 (this thread meets client requests) signals arrives.我在编写 UDP 聊天服务器时遇到了类似的问题:有一个 thread_1 仅在警报中断(超时以查看客户端是否还活着)或另一个 thread_2(该线程满足客户端请求)信号到达时才起作用。 What I did was put this thread_1 to sleep ( sleep(n*TICK_TIMER) , where TICK_TIMER is the alarm expiration value, n is some integer >1), and wake up this thread with SIGALRM signal.我所做的是让这个 thread_1 进入睡眠状态( sleep(n*TICK_TIMER) ,其中 TICK_TIMER 是警报到期值,n 是某个大于 1 的整数),并用SIGALRM信号唤醒这个线程。 See sleep() doc 参见 sleep() 文档

The alarm handler ( to use this you have to init it: "signal(SIGALRM, tick_handler); alarm(5);")警报处理程序(要使用它,您必须初始化它:“信号(SIGALRM,tick_handler);警报(5);”)

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

will send a SIGALRM when timeout occurs.超时发生时将发送SIGALRM

And the command to wake this sleep thread_1 from another thread_2 is:从另一个线程_2唤醒这个睡​​眠线程_1的命令是:

    pthread_kill(X,SIGALRM);

where X is a pthread_t type.其中 X 是pthread_t类型。 If your thread_1 is your main thread, you can get this number by pthread_t X = pthread_self();如果你的 thread_1 是你的主线程,你可以通过pthread_t X = pthread_self();得到这个数字pthread_t X = pthread_self();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM