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

14,200

Solution 1

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).

Solution 2

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);

Solution 3

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

Share:
14,200
liv2hak
Author by

liv2hak

Updated on June 05, 2022

Comments

  • liv2hak
    liv2hak almost 2 years

    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?