How do I wake up a sleeping pthread?
What you are looking for is pthread_cond_t
object, pthread_cond_timedwait
and pthread_cond_wait
functions. You could create conditional variable isThereAnyTaskToDo and wait on it in event thread. When new event is added, you just wake event thread with pthread_cond_signal()
.
You have several possibilities both on *NIX platforms and on Windows. Your timer thread should wait using some kind of timed wait on event/conditional variable object. On POSIX platforms you can use pthread_cond_timedwait()
. On Windows, you can either choose to compute the necessary time delta and use WaitForSingleObject()
on event handle, or you could use combination of event object with CreateTimerQueueTimer()
or CreateWaitableTimer()
. Boost does also have some synchronization primitives that you could use to implement this with the POSIX-like primitives but portably.
UPDATE:
POSIX does have some timer functionality as well, see create_timer()
I agree with Greg and wilx - pthread_cond_timedwait()
can be used to implement the behaviour you're after. I just wanted to add that you can simplify your event thread main loop:
- try to get the next event in the event queue
- If there is no pending event, go straight to 4
- Get the time that the next event is supposed to occur
- Wait on condition variable with
pthread_cond_timedwait()
until next event (or withpthread_cond_wait()
if no scheduled events) - Try to get the next event in the event queue
- If there are no events that have expired yet, go back to 4
- Update queue (remove event, re-insert if it's a repeating event)
- Jump back to 5
So you don't care why you woke up - whenever you wake up, you check the current time and run any events that have expired, then go back to waiting. In most cases when a new event is added you'll find that no events have expired, of course - you'll just recalculate the wait time.
You'll probably want to implement the queue as a Priority Queue, so that the next-event-to-expire is always at the front.