I am moving a C program using pthreads
over to C++ and will have to make extensive use of the Boost library for the sake of making the program multi-platform, portable, etc.
When working with a thread in the past, my code will usually have the form:
void threadFunc(void* pUserData)
{
if ( !pUserData )
{
return;
}
myStruct* pData = (myStruct*)pUserData;
bool bRun;
lock(pUserData);
bRun = pUserData->bRun;
unlock(pUserData);
while ( bRun )
{
// Do some stuff
// ...
// ...
lock(pUserData);
bRun = pUserData->bRun;
unlock(pUserData);
}
/* Done execution of thread; External thread must have set pUserData->bRun
* to FALSE.
*/
}
This works as I would expect. When I want the thread to shut down, I just lock the mutex for the struct
it's accessing (typically a member of the struct
), toggle the bRun
flag, and join()
on the thread. For boost threads, I've noticed cases with my code where a timed_join()
times out when doing non-blocking operations, similar to this SO question. This leads me to suspect I'm not using boost threads correctly.
To the question...
First, which of the two general thread structures would be correct for having a thread properly catch the thread_interrupted
exception?
Case A
void threadFunc( void* pUserData )
{
while ( 1 )
{
try
{
// Do some stuff
// ...
// ...
boost::this_thread::sleep(boost::posix_time::milliseconds(1));
}
catch(boost::thread_interrupted const& )
{
// Thread interrupted; Clean up
}
}
}
Case B
void threadFunc( void* pUserData )
{
try
{
while ( 1 )
{
// Do some stuff
// ...
// ...
boost::this_thread::sleep(boost::posix_time::milliseconds(1));
}
}
catch(boost::thread_interrupted const& )
{
// Thread interrupted; Clean up
}
}
Second, what would be the appropriate boost function to call in place of sleep if I want the thread to have a chance to catch the interrupt call, but not to sleep()
or give up the remainder of the CPU time slice it currently holds? From another SO question on this topic, it seems that the boost::this_thread::interruption_point()
call might be what I'm looking for, but I'm not 100% sure if it will always work, from what I read in the SO question I referenced it from.
Finally, it's to my understanding that not calling any manner of boost sleep()
function or some similar interruption point function in my loop will mean that a timed_join()
will always timeout, and I'll either have to:
- Forcefully kill the thread.
- Fall back to using a mutex protected flag like in my original C code.
Is this assumption correct?
Thank you.
References
- Boost Thread - How to acknowledge interrupt,
<https://stackoverflow.com/questions/7316633/boost-thread-how-to-acknowledge-interrupt>
, Accessed 2016-01-18. - boost::this_thread::interruption_point() doesn't throw boost::thread_interrupted& exception,
<https://stackoverflow.com/questions/26103648/boostthis-threadinterruption-point-doesnt-throw-boostthread-interrupted>
, Accessed 2016-01-18.