Boost (v1.33.1) Thread Interruption - c++

How can I interrupt a sleeping/blocked boost::thread?
I am using Boost v1.33.1, upgrading is not an option.
Thank you.

A quick perusal of the documentation for boost.thread in 1.33 suggests that there is no portable way to achieve interruption. Thread interruption was introduced (for threads in one of the boost "interruption points") in 1.35.
As a result the only option I can think of is to use signals (which aren't in 1.33 either, so you'll need to fall back on, for example, pthreads) combined with time-outs on any methods that are blocking. Basically use signals to wake threads that are asleep by having them sleep waiting for the signal and timeouts on blocking threads to have them wake up and check to see if they should exit. Unfortunately this is a highly undesirable solution, and to some extent amounts to what newer versions of boost do internally anyway.
If you're using boost.thread, then you should consider upgrading to a more recent version for other projects because 1.33 doesn't support the vast majority of constructs that are essential for multi-threading.

I agree with begray, look into condition variables. If you have threads you want to wake up from time to time, they are what boost expects you to use. If you expect that threads are going to block on other calls (like calls into BSD sockets or something similar) this doesn't help you. You will need to use the timeout facilities of those calls directly, if they exist.
Here's an example, using only facilities available in boost 1.33.1. I haven't compiled it, so there may be small errors. I've included the use of a nebulous Work class, but you don't need to work with shared data at all to use this pattern. Only the mutex and the condition variable are needed.
Work work;
boost::condition workAvailable;
boost::mutex workMutex;
void Producer()
{
{
boost::mutex::scoped_lock lock(workMutex);
UpdateWork(work);
workAvailable.notify_one();
}
boost::mutex::scoped_lock lock(workMutex);
work.SetOver();
workAvailable.notify_one();
}
void Consumer()
{
//This thread uses data protected by the work mutex
boost::mutex::scoped_lock lock(workMutex);
while(true)
{
//this call releases the work mutex
//when this thread is notified, the mutex is re-acquired
workAvailable.wait(lock);
//once we have the mutex we can work with shared data
//which might require this thread to terminate
if(work.Over())
{
return;
}
DoWork(work);
}
}
The producer thread will create one unit of work, and then block. The consumer thread will do the work, and then block. Then the producer thread will set the termination condition and exit. The consumer will then exit.

There is no way to interrupt blocked thread in boost::thread. You need to implement proper thread interruption yourself, using boost::conditional for example.
AFAIK Any existing ways to interrupt running thread (TerminateThread in Windows API for example) only lead to problems (memory leaks one of them).

Related

Can std::lock_guard be interupted?

If I have some code under lock_guard like:
std::thread t([&]()
{
std::lock_guard<std::mutex> lock(m);
// some simple operations
});
Do I have a guarantee that "some operations" will never be interrupted on this core cpu that t thread is running? Can there be context switching after lock_guard?
There will be context switches but it is guaranteed that all other threads will be blocked behind the lock.
No, a critical section protected by a mutex is not going to run with real-time priority unless you explicitly request it to do so, which cannot be done using the standard C++ library. The kernel can still schedule another thread (in the same process, or some other process) that isn't waiting on the mutex. Setting real-time priority can only be done with OS-specific system calls.

synchronization between threads using tbb

I am using tbb programming in C++. I am not supposed to use message queue, FIFO, PIPES etc as it is platform specific. I am supposed to use tbb specific API's.
Thread1: // Pseuodo code exits as below
// I will take mutex
m_bIsNewSubsArrived = true;
StartSubscriptionTimer();
m_bIsFristSubsArrived = true;
// Spawn a thread here.
if(m_tbbTimerThread == NULL)
{
m_bIsTimerMutexTaken = true;
m_timerMutex.lock();
m_tbbTimerThread = new tbb::tbb_thread(&WaitForTimerMutex, this);
if (m_tbbTimerThread->native_handle() == 0)
{
// report error and return.
return;
}
}
// Thread 1 exited.
In another thead I am releasing mutex which is taken above.
Thread 2.
m_timerMutex.unlock();
m_bIsTimerMutexTaken = false;
Thread 3:
// I am waiting for mutex
m_timerMutex.lock();
In above code problem I think is thread 1 which locked m_timerMutex is not relased so I think thread2 not able to unlock. And thread 3 is blocked for ever.
I think I can use sempahore, but what are API's for sempahore in TBB.
What is the best technique I can do this with out sleeping and using tbb specific API's.
Thanks for your time and help.
There is currently no support for semaphores in TBB. The reason is that TBB is intended to raise the level of abstraction above raw threads to the level of tasks, and semaphores are considered a low-level "goto" of threaded programming. Note that C++11 does not have semaphores either.
Using tasks instead of threads often allows synchronization to become implicit, and often permits automatic load balancing via the work-stealing scheduler in TBB.
If your problem is not amenable to a task-based solution, consider using condition variables, which are part of C++11. Recent versions of TBB ship with a partial implementation of C++11 condition variables.
I've never used tbb, but typically you can only release a mutex in the thread currently holding it (which is kind of the purpose of a mutex). From the code shown here, Thread1 is still holding the mutex, Thread2 can't release it because it doesn't hold it (don't know what the behavior is there in the Intel implementation, have to look this up) and Thread3 is waiting forever because Thread1 is still holding the mutex.
(But I'm just guessing, because you didn't tell us what's actually happening with the code you've got so far, or what exactly you are trying to do)

Is there a way to find out, whether a thread is blocked?

I'm writing a thread pool class in C++ which receives tasks to be executed in parallel. I want all cores to be busy, if possible, but sometimes some threads are idle because they are blocked for a time for synchronization purposes. When this happens I would like to start a new thread, so that there are always approximately as many threads awake as there are cpu cores. For this purpose I need a way to find out whether a certain thread is awake or sleeping (blocked). How can I find this out?
I'd prefer to use the C++11 standard library or boost for portability purposes. But if necessary I would also use WinAPI. I'm using Visual Studio 2012 on Windows 7. But really, I'd like to have a portable way of doing this.
Preferably this thread-pool should be able to master cases like
MyThreadPool pool;
for ( int i = 0; i < 100; ++i )
pool.addTask( &block_until_this_function_has_been_called_a_hundred_times );
pool.join(); // waits until all tasks have been dispatched.
where the function block_until_this_function_has_been_called_a_hundred_times() blocks until 100 threads have called it. At this time all threads should continue running. One requirement for the thread-pool is that it should not deadlock because of a too low number of threads in the pool.
Add a facility to your thread pool for a thread to say "I'm blocked" and then "I'm no longer blocked". Before every significant blocking action (see below for what I mean by that) signal "I'm blocked", and then "I'm no longer blocked" afterwards.
What constitutes a "significant blocking action"? Certainly not a simple mutex lock: mutexes should only be held for a short period of time, so blocking on a mutex is not a big deal. I mean things like:
Waiting for I/O to complete
Waiting for another pool task to complete
Waiting for data on a shared queue
and other similar events.
Use Boost Asio. It has its own thread pool management and scheduling framework. The basic idea is to push tasks to the io_service object using the post() method, and call run() from as many threads as many CPU cores you have. You should create a work object while the calculation is running to avoid the threads from exiting if they don't have enough jobs.
The important thing about Asio is never to use any blocking calls. For I/O calls, use the asynchronous calls of Asio's own I/O objects. For synchronization, use strand objects instead of mutexes. If you post functions to the io service that is wrapped in a strand, then it ensures that at any time at most one task runs that belongs to a certain strand. If there is a conflict, the task remains in Asio's event queue instead of blocking a working thread.
There is one drawback of using asynchronous programming though. It is much harder to read a code that is scattered into several asynchronous calls than one with a clear control flow. You should be aware of this when designing your program.

Cancelling a thread that has a mutex locked does not unlock the mutex

helping a client out with an issue that they are having. I'm more of a sysadmin/DBA guy so I'm struggling with helping them out. They are saying it is a bug in the kernel/environment, I'm trying to either prove or disprove that before I insist that it is in their code or seek vendor support for the OS.
Happens on Red Hat and Oracle Enterprise Linux 5.7 (and 5.8), application is written in C++
The problem they are experiencing is that the main thread starts a separate thread to do a potentially long-running TCP connect() [client connecting to server].
If the 'long-running' aspect takes too long, they cancel the thread and start another one.
This is done because we don't know the state of the server program:
server program up and running --> connection immediately accepted
server program not running, machine and network OK --> connection
immediately failed with error 'connection refused'
machine or network crashed or down --> connection takes a long time
to fail with error 'no route to host'
The problem is that cancelling the thread that has the mutex locked
(with cleanup handlers set up to unlock the mutex) sometimes does NOT unlock the mutex.
That leaves the main thread hung on trying to lock the mutex.
Detailed environment info:
glibc-2.5-65
glibc-2.5-65
libcap-1.10-26
kernel-debug-2.6.18-274.el5
glibc-headers-2.5-65
glibc-common-2.5-65
libcap-1.10-26
kernel-doc-2.6.18-274.el5
kernel-2.6.18-274.el5
kernel-headers-2.6.18-274.el5
glibc-devel-2.5-65
Code was built with:
c++ -g3 tst2.C -lpthread -o tst2
Any advice and guidance is greatly appreciated
It's correct that cancelled threads do not unlock mutexes they hold, you need to arrange for that to happen manually, which can be tricky as you need to be very careful to use the right cleanup handlers around every possible cancellation point. Assuming you're using pthread_cancel to cancel the thread and setting cleanup handlers with pthread_cleanup_push to unlock the mutexes, there are a couple of alternatives you could try which might be simpler to get right and so may be more reliable.
Using RAII to unlock the mutex will be more reliable. On GNU/Linux pthread_cancel is implemented with a special exception of type __cxxabi::__forced_unwind, so when a thread is cancelled an exception is thrown and the stack is unwound. If a mutex is locked by an RAII type then its destructor will be guaranteed to run if the stack is unwound by a __forced_unwind exception. Boost Thread provides a portable C++ library that wraps Pthreads and is much easier to use. It provides an RAII type boost::mutex and other useful abstractions. Boost Thread also provides its own "thread interruption" mechanism which is similar to Pthread cancellation but not the same, and Pthread cancellation points (such as connect) are not Boost Thread interruption points, which can be helpful for some applications. However in your client's case since the point of cancellation is to interrupt the connect call they probably do want to stick with Pthread cancellation. The (non-portable) way GNU/Linux implements cancellation as an exception means it will work well with boost::mutex.
There is really no excuse for explicitly locking and unlocking mutexes when you're writing in C++, IMHO the most important and most useful feature of C++ is destructors which are ideal for automatically releasing resources such as mutex locks.
Another option would be to use a robust mutex, which is created by calling pthread_mutexattr_setrobust on a pthread_mutexattr_t before initializing the mutex. If a thread dies while holding a robust mutex the kernel will make a note of it so that the next thread which tries to lock the mutex gets the special error code EOWNERDEAD. If possible, the new thread can make the data protected by the thread consistent again and take ownership of the mutex. This is much harder to use correctly than simply using an RAII type to lock and unlock the mutex.
A completely different approach would be to decide if you really need to hold the mutex lock while calling connect. Holding mutexes during slow operations is not a good idea. Can't you call connect then if successful lock the mutex and update whatever shared data is being protected by the mutex?
My preference would be to both use Boost Thread and avoid holding the mutex for long periods.
The problem they are experiencing is that the main thread starts a separate thread to do a potentially long-running TCP connect() [client connecting to server]. If the 'long-running' aspect takes too long, they cancel the thread and start another one.
Trivial fix -- don't cancel the thread. Is it doing any harm? If necessary, have the thread check (when the connect finally does complete) whether the connection is still needed and, if not, close it, release the mutex, and terminate. You can do this with a boolean variable protected by a mutex.
Also, a thread should not hold a mutex while waiting for network I/O. Mutexes should be used only for things that are fast and primarily CPU-limited or perhaps limited by local disk.
Finally, if you feel you need to reach in from the outside and force a thread to do something, step back. You wrote the code for that thread. If you feel that need, it means you didn't code that thread to do what you really wanted it to do. The fix is to modify the thread to do what, and only what, you actually want. Then you won't have to "push it around" from the outside.

learning threads on linux

Linux is a new platform to me. I've coded on Windows in c++ for a number of years and have become comfortable with multithreading on that platform.
Along comes C++11 at a time when I need to learn c++ on the linux platform.
Linux appears to use pthreads for the most part - okay there's also boost::threads and QT have their own threads too. But with C++11 comes std::thread, a whole new (cross platform and C++ standard) way to do threads.
So I guess I'll have to learn pthreads and std::threads. Ultimately, std::thread seems more important, but there's a lot of legacy code out there, so I'll have to know both.
For thread synchronization on windows, I would use WaitForMultipleObjects to wait for a number of tasks to complete before continuing with further work.
Does a similar synchronization mechanism exist for pthreads? std::threads?
I've had a look at pthread_join, and it seems to have the facility to only wait on one thread at a time. Am I missing another pthread call maybe?
std::thread is boost::thread accepted into C++11 with some extras. My understanding is that if boost::thread gets replaced in code with std::thread it should still compile and work.
boost::thread is based on pthreads design, providing thin C++ wrappers over thread, mutex and condition variables. Thread cancellation though was left outside the scope of C++11, since there was no agreement how it should work in C++.
So, by learning pthreads you also learn std::thread concepts. std::thread adds mostly syntax sugar and convenience functions on top of pthreads C API.
With regards to WaitForMultipleObjects(), neither pthreads nor std::thread provide anything similar to its bWaitAll=FALSE mode, however, it's routinely simulated using pipes and select() on UNIX, or more modern eventfd() and epoll() on Linux. bWaitAll=TRUE mode can be simulated by waiting on all tasks in turn, since it doesn't proceed until all objects are ready anyway.
No, neither pthreads nor C++11 has direct equivalent of WaitForMultipleObjects (i.e. wait for any waitable "handle" type.) pthread_join can only be used to join threads, and only a single, specific thread.
The closest equivalent on posix platforms is to wait for multiple file descriptors using system calls such as select(), poll() or the linux-specific epoll(), but they require you to have a file descriptor to wait on, which is fine for I/O events but requires extra work from you to use them wait for mutexes, condition variables or other synchronisation objects. There are more general event libraries built on top of those system calls, e.g. libevent and libev and Boost ASIO, which support waiting for timers as well as I/O, but still not thread completion, mutex locks etc. with a single function like WaitForMultipleObjects
The alternatives you do have for pthreads and C++11 threads are to wait on different synchronisation types separately. You can wait for timers, wait for threads to complete, wait for mutexes, wait on condition variables, wait for asynchronous results to be ready (std::async in C++11, no direct equivalent in pthreads) ... but there's no call that will allow you to wait a heterogeneous set of those types all at once.
I could give you a really fancy answer but alas, this is where I learned them and it is a good introduction:
http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
You use pthread_mutex_t for syncronization and pthread_join probably handles the wait for multiple tasks problem. It works exactly as you would expect.
Based on this, you must call pthread_join for each single thread you have created. Or to use mutexes, if there is a need to synchronize your threads.
Regarding WaitForMultipleObjects, this is generally called a Barrier Sync. Boost has an implementation called barrier. It uses conditional variables to implement it, in posix its a pthread_cond_t
Here is an answer I left recently explaining barrier sync.