Reputation: 2983
I have a thread that waits (blocking) on a message queue for messages to process. Polling is not an option.
When a certain START message arrives, we set some variable which must then either reset after a given time delay, or be reset by the arrival of another STOP message. If it is set, a repeated START should extend the set-time by a given time period (could just re-start).
In the meantime, the thread should carry on processing other messages which arrive.
To my mind, the way to do this is spawn and detach a new pthread which will handle the time-out. This thread will either time-out and send a STOP message to the parent before exiting, or be killed/cancelled prematurely if a STOP message is received by the parent thread.
I've been reading the pthreads documentation and it's not entirely clear to me the best way of doing this:
I could create a thread that just sleeps for a given time and then sends the STOP message, and pthread_cancel() it if a STOP message arrives sooner. It seems to be implied in the docs (but not explicitly stated) that, in this case, the "cancel" action would basically kill the thread mid-sleep, no further actions.
I could create a thread which uses pthread_cond_timedwait() to wait on a condition, as per this example. This looks the most "proper" but also the most cumbersome.
Something similar to 1 but fork()ing a process which watches a flag variable and either times out or gives up if the flag is reset.
Use SIGALARM handler, plus Alarm() to set / unset a timed signal (sounds simple, but practice seems a bit untidy and you can only have one alarm)
Delays are in the seconds range, accuracy to ~0.1sec would be nice. I'm not keen on the way pthread_cond_timedwait uses an absolute time, as there's a chance the user may set the clock and throw things out of kilter (not the end of the world, but it just seems non-optimal to me).
It's not clear to me from the examples around the net that either "pthread_cancel" or "pthread_cond_timedwait" work / work cleanly for a detached thread?
I won't post code of my current favoured option as it would pretty much be a copy-paste of the example in option 2.
Upvotes: 0
Views: 1597
Reputation: 27542
I don't see what you are agonizing over. As best as I understand your description, timers are plainly the way to go.
timer_create
to deliver a signal if time elapses. If all you are doing is setting a switch on variable this is easily done in the signal handler itselftimer_settime
timer_gettime
, add the new amount of time to it, and reset the timer with timer_settime
.Unlike alarm
or the itimer
interval timers you are not limited to a single timer.
As an aside, if you are using POSIX message queues and your messages are few and far between it may be worth using mq_notify
. Instead of blocking on mq_receive
all day you can set it to spin up a thread whenever a new message is put in a previously empty queue and you just process any and all messages until the queue is again empty and the thread ends.
Upvotes: 1