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
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.
How do I wake up the sleeping thread (that runs the report()) when the timer goes off in the main thread?
You can sleep a thread using sigwait, and then signal that thread to wake up with pthread_kill. Kill sounds bad, but it doesn't kill the thread, it sends a signal. 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?
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. 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. See sleep() doc
The alarm handler ( to use this you have to init it: "signal(SIGALRM, tick_handler); alarm(5);")
void tick_handler(){tick_flag++; alarm(5); }
will send a SIGALRM
when timeout occurs.
And the command to wake this sleep thread_1 from another thread_2 is:
pthread_kill(X,SIGALRM);
where X is a pthread_t
type. If your thread_1 is your main thread, you can get this number by pthread_t X = pthread_self();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.