views:

312

answers:

2

I have a developed a simple polling thread (using Boost 1.39.0) which checks whether a data resource has been accessed within a given timeframe and clears the connection if not. The relevant code can be reviewed below.

My concerns are twofold:

1) Is using interrupt on a sleep appropriate to close down the thread safely? Will the interrrupt wait for the sleep to finish or will it interupt immediately? You can see I catch a thread_interrupted exception just to escape the while loop.

2) Is using a thread which spends most of its time asleep wasteful? Is there a better pattern to implement a simple polling mechanism in standard C++?

boost::xtime xt;

while (1) {
 try {
  boost::xtime_get(&xt, boost::TIME_UTC);
  xt.sec += _sleep_secs;
  boost::thread::sleep(xt);
  //
  // logic to check resource access
  // etc.
 } 
 catch(boost::thread_interrupted const&) {
  return;
 }
}
+2  A: 

1) It must be safe judging from Boost implementation of boost::thread::interrupt() for POSIX threads:

void thread::interrupt()
{
    detail::thread_data_ptr const local_thread_info=get_thread_info();
    if(local_thread_info)
    {
        lock_guard<mutex> lk(local_thread_info->data_mutex);
        local_thread_info->interrupt_requested=true;
        if(local_thread_info->current_cond)
        {
            BOOST_VERIFY(!pthread_cond_broadcast(local_thread_info->current_cond));
        }
    }
}

They lock mutex, set interrupt_requested to true and broadcast on a conditional variable. And the thread will be waken up immediately if it sleeps in boost::thread::sleep(). And they don't use pthread_cancel in it on order ot cancel a thread.

2) I don't think one thread is a waste of resources if we talk about such operating systems as Windows, Linux or HP-UX. This is a quote to support this point:

Many OS's also have trouble handling more than a few hundred threads. If each thread gets a 2MB stack (not an uncommon default value), you run out of virtual memory at (2^30 / 2^21) = 512 threads on a 32 bit machine with 1GB user-accessible VM (like, say, Linux as normally shipped on x86)

.

skwllsp
Thanks, I've been running it my dev environemnt and it seems to work as expected. I need to spend some time getting to properly understand threading though.
Michael
A: 

I think that use is perfectly all right, many people use it (think shutdown sequence, when you need to close threads - you'd interrupt() all then they can shutdown).

Regarding boost though, make sure you read the documentation: in particular, only a handful of instructions are "interruption points", which means the thread will be interrupted and get that exception only if you interrupt while that instruction is being executed. If the thread is doing something else, you'll only get the interrupt when you enter an interruption point, which might a while after requesting the interrupt, depending on what you're doing in your thread.

I think that's true in any case, that's how I interpret the following:

the thread will be interrupted the next time it enters one of the predefined interruption points with interruption enabled, or if it is currently blocked in a call to one of the predefined interruption points with interruption enabled .

from the boost thread documentation

laura
Thanks for your help. Its great to get some good advice as boost threading documentation can be quite challenging to digest for someone not used to doing a lot of (or any?) thread programming.
Michael