John U
John U

Reputation: 2983

pthread time-out or cancel, using pthread_cond_timedwait, or what?

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:

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

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

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

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

Answers (1)

Duck
Duck

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.

  • create a timer with 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 itself
  • if you get a STOP message while there is time remaining, disarm the timer with timer_settime
  • if you get a 2nd START msg while the timer is armed get the time remaining on the timer with timer_gettime, add the new amount of time to it, and reset the timer with timer_settime.
  • delete the timer when you are done with it with timer_delete

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

Related Questions