[英]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.