Locking C++11 std::unique_lock causes deadlock exception - linux

I'm trying to use a C++11 std::condition_variable, but when I try to lock the unique_lock associated with it from a second thread I get an exception "Resource deadlock avoided". The thread that created it can lock and unlock it, but not the second thread, even though I'm pretty sure the unique_lock shouldn't be locked already at the point the second thread tries to lock it.
FWIW I'm using gcc 4.8.1 in Linux with -std=gnu++11.
I've written a wrapper class around the condition_variable, unique_lock and mutex, so nothing else in my code has direct access to them. Note the use of std::defer_lock, I already fell in to that trap :-).
class Cond {
private:
std::condition_variable cCond;
std::mutex cMutex;
std::unique_lock<std::mutex> cULock;
public:
Cond() : cULock(cMutex, std::defer_lock)
{}
void wait()
{
std::ostringstream id;
id << std::this_thread::get_id();
H_LOG_D("Cond %p waiting in thread %s", this, id.str().c_str());
cCond.wait(cULock);
H_LOG_D("Cond %p woke up in thread %s", this, id.str().c_str());
}
// Returns false on timeout
bool waitTimeout(unsigned int ms)
{
std::ostringstream id;
id << std::this_thread::get_id();
H_LOG_D("Cond %p waiting (timed) in thread %s", this, id.str().c_str());
bool result = cCond.wait_for(cULock, std::chrono::milliseconds(ms))
== std::cv_status::no_timeout;
H_LOG_D("Cond %p woke up in thread %s", this, id.str().c_str());
return result;
}
void notify()
{
cCond.notify_one();
}
void notifyAll()
{
cCond.notify_all();
}
void lock()
{
std::ostringstream id;
id << std::this_thread::get_id();
H_LOG_D("Locking Cond %p in thread %s", this, id.str().c_str());
cULock.lock();
}
void release()
{
std::ostringstream id;
id << std::this_thread::get_id();
H_LOG_D("Releasing Cond %p in thread %s", this, id.str().c_str());
cULock.unlock();
}
};
My main thread creates a RenderContext, which has a thread associated with it. From the main thread's point of view, it uses the Cond to signal the rendering thread to perform an action and can also wait on the COnd for the rendering thread to complete that action. The rendering thread waits on the Cond for the main thread to send rendering requests, and uses the same Cond to tell the main thread it's completed an action if necessary. The error I'm getting occurs when the rendering thread tries to lock the Cond to check/wait for render requests, at which point it shouldn't be locked at all (because the main thread is waiting on it), let alone by the same thread. Here's the output:
DEBUG: Created window
DEBUG: OpenGL 3.0 Mesa 9.1.4, GLSL 1.30
DEBUG: setScreen locking from thread 140564696819520
DEBUG: Locking Cond 0x13ec1e0 in thread 140564696819520
DEBUG: Releasing Cond 0x13ec1e0 in thread 140564696819520
DEBUG: Entering GLFW main loop
DEBUG: requestRender locking from thread 140564696819520
DEBUG: Locking Cond 0x13ec1e0 in thread 140564696819520
DEBUG: requestRender waiting
DEBUG: Cond 0x13ec1e0 waiting in thread 140564696819520
DEBUG: Running thread 'RenderThread' with id 140564575180544
DEBUG: render thread::run locking from thread 140564575180544
DEBUG: Locking Cond 0x13ec1e0 in thread 140564575180544
terminate called after throwing an instance of 'std::system_error'
what(): Resource deadlock avoided
To be honest I don't really understand what a unique_lock is for and why condition_variable needs one instead of using a mutex directly, so that's probably the cause of the problem. I can't find a good explanation of it online.

Foreword: An important thing to understand with condition variables is that they can be subject to random, spurious wake ups. In other words, a CV can exit from wait() without anyone having called notify_*() first. Unfortunately there is no way to distinguish such a spurious wake up from a legitimate one, so the only solution is to have an additional resource (at the very least a boolean) so that you can tell whether the wake up condition is actually met.
This additional resource should be guarded by a mutex too, usually the very same you use as a companion for the CV.
The typical usage of a CV/mutex pair is as follows:
std::mutex mutex;
std::condition_variable cv;
Resource resource;
void produce() {
// note how the lock only protects the resource, not the notify() call
// in practice this makes little difference, you just get to release the
// lock a bit earlier which slightly improves concurrency
{
std::lock_guard<std::mutex> lock(mutex); // use the lightweight lock_guard
make_ready(resource);
}
// the point is: notify_*() don't require a locked mutex
cv.notify_one(); // or notify_all()
}
void consume() {
std::unique_lock<std::mutex> lock(mutex);
while (!is_ready(resource))
cv.wait(lock);
// note how the lock still protects the resource, in order to exclude other threads
use(resource);
}
Compared to your code, notice how several threads can call produce()/consume() simultaneously without worrying about a shared unique_lock: the only shared things are mutex/cv/resource and each thread gets its own unique_lock that forces the thread to wait its turn if the mutex is already locked by something else.
As you can see, the resource can't really be separated from the CV/mutex pair, which is why I said in a comment that your wrapper class wasn't really fitting IMHO, since it indeed tries to separate them.
The usual approach is not to make a wrapper for the CV/mutex pair as you tried to, but for the whole CV/mutex/resource trio. Eg. a thread-safe message queue where the consumer threads will wait on the CV until the queue has messages ready to be consumed.
If you really want to wrap just the CV/mutex pair, you should get rid of your lock()/release() methods which are unsafe (from a RAII point of view) and replace them with a single lock() method returning a unique_ptr:
std::unique_ptr<std::mutex> lock() {
return std::unique_ptr<std::mutex>(cMutex);
}
This way you can use your Cond wrapper class in rather the same way as what I showed above:
Cond cond;
Resource resource;
void produce() {
{
auto lock = cond.lock();
make_ready(resource);
}
cond.notify(); // or notifyAll()
}
void consume() {
auto lock = cond.lock();
while (!is_ready(resource))
cond.wait(lock);
use(resource);
}
But honestly I'm not sure it's worth the trouble: what if you want to use a recursive_mutex instead of a plain mutex? Well, you'd have to make a template out of your class so that you can choose the mutex type (or write a second class altogether, yay for code duplication). And anyway you don't gain much since you still have to write pretty much the same code in order to manage the resource. A wrapper class only for the CV/mutex pair is too thin a wrapper to be really useful IMHO. But as usual, YMMV.

Related

Is it safe to initialize a c++11 function-static variable from a linux signal handler?

2 questions (below) about the C++11 static initialization at [1] in this reference code (this is a complete tested c++11 example program).
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
struct Foo {
/* complex member variables. */
};
void DoSomething(Foo *foo) {
// Complex, but signal safe, use of foo.
}
Foo InitFoo() {
Foo foo;
/* complex, but signal safe, initialization of foo */
return foo;
}
Foo* GetFoo() {
static Foo foo = InitFoo(); // [1]
return &foo;
}
void Handler(int sig) {
DoSomething(GetFoo());
}
int main() {
// [2]
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_handler = Handler;
sigaction(SIGINT, &act, nullptr);
for (;;) {
sleep(1);
DoSomething(GetFoo());
}
}
Question1: Is this guaranteed safe (no deadlocks etc)? C++11 static initialization involves locks. What if the signal is delivered before/after/during the first call to GetFoo() in main?
Question2: Is this guaranteed safe if a call to GetFoo() is inserted at [2] before the signal handler is installed? (Edit:) I.e. does inserting GetFoo() at [2] ensure that, later, when a signal arrives while the loop is operating, that there will be no deadlock?
I'm assuming C++11 (g++ or clang) on recent GNU/Linux, although answers for various Unices would also be interesting. (Spoiler: I think the answer is 1:NO and 2:YES but I don't know how to prove it.)
Edit: To be clear, I can imagine static initialization could be implemeted like this:
Mutex mx; // global variable
bool done = false; // global variable
...
lock(mx);
if (!done) {
foo = InitFoo();
done = true;
}
unlock(mx);
and then it would not be deadlock safe because the signal handler might lock mx while the main thread has it locked.
But there are other implementations, for example:
Mutex mx; // global variable
std::atomic<bool> done = false; // global variable
...
if (!done.load()) {
lock(mx);
if (!done.load()) {
foo = InitFoo();
done.store(true);
}
unlock(mx);
}
which would not have potential for deadlock provided the codepath was run completely at least once before a signal handler runs it.
My question is whether the c++11 (or any later) standard requires the implementation to be async-signal-safe (deadlock free, aka lock free) after the initial pass through the code has completed?
How static Foo foo = InitFoo(); gets initialized must be stated first before getting into signals.
It requires dynamic initialization, where it'll be initialized the first time GetFoo() gets called since the "complex initialization" you mention in InitFoo() can't be done at compile-time:
Dynamic initialization of a block-scope variable with static storage
duration or thread storage duration is performed the first time
control passes through its declaration; such a variable is considered
initialized upon the completion of its initialization. If the
initialization exits by throwing an exception, the initialization is
not complete, so it will be tried again the next time control enters
the declaration. If control enters the declaration concurrently while
the variable is being initialized, the concurrent execution shall wait
for completion of the initialization. 85 If control re-enters the declaration recursively while the variable is being initialized, the
behavior is undefined.
85 The implementation must not introduce any deadlock around execution of the initializer. Deadlocks might still be caused by the program logic; the implementation need only avoid deadlocks due to its own synchronization operations.
With that established, we can go to the questions.
Question1: Is this guaranteed safe (no deadlocks etc)? C++11 static initialization involves locks. What if the signal is delivered before/after/during the first call to GetFoo() in main?
No, this isn't guaranteed. Consider when GetFoo() is called the first time from inside the for loop:
GetFoo() -> a lock is taken to initialize 'foo'-> a signal arrives [control goes to signal handling function] -> blocked here for signal handling to complete
--> Handler() -> DoSomething(GetFoo()) -> GetFoo() -> waits here because the lock is unavailable.
(The signal handler has to wait here since the initialization of 'foo' isn't complete yet -- refer the quote above).
So the deadlock occurs in this scenario (even without any threads) as the thread is blocked on itself.
Question2: Is this guaranteed safe if a call to GetFoo() is inserted at [2] before the signal handler is installed?
In this case, there's no signal handler established at all for SIGINT. So if SIGINT arrives, the program simply exits. The default disposition for SIGINT is to terminate the process. It doesn't matter whether the initialization of GetFoo() is progress or not. So this is fine.
The fundamental problem with case (1) is that the signal handler Handler isn't async-signal-safe because it calls GetFoo() which isn't async-signal-safe.
Re. updated question with possible implementations of static initialization:
The C++11 standard only guarantees that the initialization of foo is done in a thread-safe manner (see the bold quote above). But handling signals is not "concurrent execution". It's more like "recursively re-entering" as it can happen even in a single-threaded program - and thus it'd be undefined. This is true even if static initialization is implemented like in your second method that'd avoid deadlocks.
Put it the other way: if static initialization is implemented like your first method, does it violate the standard? The answer is no. So you can't rely on static initialization being implemented in an async-signal-safe way.
Given you ensure "...provided the codepath was run completely at least once before a signal handler runs it." then you could introduce another check that'd ensure GetFoo() is async-signal-safe regardless of how static initialization is implemented:
std::atomic<bool> foo_done = false;
static_assert( std::atomic<bool>::is_lock_free );
Foo* GetFoo() {
if (!foo_done) {
static Foo foo = InitFoo(); // [1]
foo_done = true;
}
return &foo;
}

thread.join does not return when called in global var destructor

Using C++11 STL with VS2013 to implementing a asynchronous print class.
Failing to get thread.join() returns with no deadlocking.
I am trying to debug and finally find this issue may caused by global/local class variable declaration. Here is the details and I dont know why it happened?
#include <iostream>
#include <string>
#include <chrono>
#include <mutex>
#include <thread>
#include <condition_variable>
#include "tbb/concurrent_queue.h"
using namespace std;
class logger
{
public:
~logger()
{
fin();
}
void init()
{
m_quit = false;
m_thd = thread(bind(&logger::printer, this));
//thread printer(bind(&logger::printer, this));
//m_thd.swap(printer);
}
void fin()
{
//not needed
//unique_lock<mutex> locker(m_mtx);
if (m_thd.joinable())
{
m_quit = true;
write("fin");
//locker.unlock();
m_thd.join();
}
}
void write(const char *msg)
{
m_queue.push(msg);
m_cond.notify_one();
}
void printer()
{
string msgstr;
unique_lock<mutex> locker(m_mtx);
while (1)
{
if (m_queue.try_pop(msgstr))
cout << msgstr << endl;
else if (m_quit)
break;
else
m_cond.wait(locker);
}
cout << "printer quit" <<endl;
}
bool m_quit;
mutex m_mtx;
condition_variable m_cond;
thread m_thd;
tbb::concurrent_queue<string> m_queue;
};
For more convenience I placed thread.join into class's destructor in order to ensure the m_thread can be quit normally.
I test the whole class and something wrong occured.
m_thd.join() never return when class logger declared as a global var
like this:
logger lgg;
void main()
{
lgg.init();
for (int i = 0; i < 100; ++i)
{
char s[8];
sprintf_s(s, 8, "%d", i);
lgg.write(s);
}
//if first call lgg.fin() here, m_thd can be joined normally
//lgg.fin();
system("pause");
//dead&blocked here and I observed that printer() finished successfully
}
If class logger declared as a local variable, it seems everything works well.
void main()
{
logger lgg;
lgg.init();
for (int i = 0; i < 100; ++i)
{
char s[8];
sprintf_s(s, 8, "%d", i);
lgg.write(s);
}
system("pause");
}
update 2015/02/27
I tried to delete std::cout in printer(), but program still blocked at same place, seems it is not the std::cout problem?
Deleting supernumerary lock in fin()
Globals and statics are constructed and destructed just prior or post to DllMain getting called respectively for DLL_PROCESS_ATTACH and DLL_PROCESS_DETACH. The problem with this is that it occurs inside the loader lock. Which is the most dangerous place on the planet to be if dealing with kernel objects as it may cause deadlock, or the application to randomly crash. As such you should never use thread primitives as statics on windows EVER. Thus dealing with threading in a destructor of a global object is basically doing the exact things we're warned not to do in DllMain.
To quote Raymond Chen
The building is being demolished. Don't bother sweeping the floor and emptying the trash cans and erasing the whiteboards. And don't line up at the exit to the building so everybody can move their in/out magnet to out. All you're doing is making the demolition team wait for you to finish these pointless housecleaning tasks.
and again:
If your DllMain function creates a thread and then waits for the thread to do something (e.g., waits for the thread to signal an event that says that it has finished initializing, then you've created a deadlock. The DLL_PROCESS_ATTACH notification handler inside DllMain is waiting for the new thread to run, but the new thread can't run until the DllMain function returns so that it can send a new DLL_THREAD_ATTACH notification.
This deadlock is much more commonly seen in DLL_PROCESS_DETACH, where a DLL wants to shut down its worker threads and wait for them to clean up before it unloads itself. You can't wait for a thread inside DLL_PROCESS_DETACH because that thread needs to send out the DLL_THREAD_DETACH notifications before it exits, which it can't do until your DLL_PROCESS_DETACH handler returns.
This also occurs even when using an EXE because the visual C++ runtime cheats and registers its constructors and destructors with the C runtime to be run when the runtime is loaded or unloaded, thus ending up with the same issue:
The answer is that the C runtime library hires a lackey. The hired lackey is the C runtime library DLL (for example, MSVCR80.DLL). The C runtime startup code in the EXE registers all the destructors with the C runtime library DLL, and when the C runtime library DLL gets its DLL_PROCESS_DETACH, it calls all the destructors requested by the EXE.
I'm wondering how you're using m_mtx. The normal pattern is that both thread lock it and both threads unlock it. But fin() fails to lock it.
Similarly unexpected is m_cond.wait(m_mtx). This would release the mutex, except that it isn't locked in the first place!
Finally, as m_mtx isn't locked, I don't see how m_quit = true should become visible in m_thd.
One problem you have is that std::condition_variable::notify_one is called while the same std::mutex that the waiting thread is holding, is held (happens when logger::write is called by logger::fin).
This causes the notified thread to immediately block again, and hence the printer thread will block possibly indefinitely upon destruction (or until spurious wakeup).
You should never notify while holding the same mutex as the waiting thread(s).
Quote from en.cppreference.com:
The notifying thread does not need to hold the lock on the same mutex as the one held by the waiting thread(s); in fact doing so is a pessimization, since the notified thread would immediately block again, waiting for the notifying thread to release the lock.

C++11 - Managing worker threads

I am new to threading in C++11 and I am wondering how to manage worker threads (using the standard library) to perform some task and then die off. I have a pool of threads vector<thread *> thread_pool that maintains a list of active threads.
Let's say I launch a new thread and add it to the pool using thread_pool.push_back(new thread(worker_task)), where worker_task is defined as follows:
void worker_task()
{
this_thread::sleep_for(chrono::milliseconds(1000));
cout << "Hello, world!\n"
}
Once the worker thread has terminated, what is the best way to reliably remove the thread from the pool? The main thread needs to run continuously and cannot block on a join call. I am more confused about the general structure of the code than the intricacies of synchronization.
Edit: It looks like I misused the concept of a pool in my code. All I meant was that I have a list of threads that are currently running.
You can use std::thread::detach to "separate the thread of execution from the thread object, allowing execution to continue independently. Any allocated resources will be freed once the thread exits."
If each thread should make its state visible, you can move this functionality into the thread function.
std::mutex mutex;
using strings = std::list<std::string>;
strings info;
strings::iterator insert(std::string value) {
std::unique_lock<std::mutex> lock{mutex};
return info.insert(info.end(), std::move(value));
}
auto erase(strings::iterator p) {
std::unique_lock<std::mutex> lock{mutex};
info.erase(p);
}
template <typename F>
void async(F f) {
std::thread{[f] {
auto p = insert("...");
try {
f();
} catch (...) {
erase(p);
throw;
}
erase(p);
}}.detach();
}

Keeping threads alive even if the main thead has terminated

I am not sure if my question is correct, but I have the following example, where the main thread creates two additional threads.
Since I am not using join command at the end of the main, it will continue execution and in the same time, the two created threads will work in parallel. But since the main is terminated before they finish their execution, I am getting the following output:
terminate called without an active exception
Aborted (core dumped)
Here's the code:
#include <iostream> // std::cout
#include <thread> // std::thread
#include <chrono>
void foo()
{
std::chrono::milliseconds dura( 2000 );
std::this_thread::sleep_for( dura );
std::cout << "Waited for 2Sec\n";
}
void bar(int x)
{
std::chrono::milliseconds dura( 4000 );
std::this_thread::sleep_for( dura );
std::cout << "Waited for 4Sec\n";
}
int main()
{
std::thread first (foo);
std::thread second (bar,0);
return 0;
}
So my question is how to keep these two threads working even if the main thread terminated?
I am asking this because in my main program, I have an event handler ,and for each event I create a corresponding thread. But the main problem when the handler creates a new thread, the handler will continue execution. Until it is destroyed which will cause also the newly created thread to be destroyed. So my question is how to keep the thread alive in this case?
Also if I use a join it will convert back to serialization.
void ho_commit_indication_handler(message &msg, const boost::system::error_code &ec)
{
.....
}
void event_handler(message &msg, const boost::system::error_code &ec)
{
if (ec)
{
log_(0, __FUNCTION__, " error: ", ec.message());
return;
}
switch (msg.mid())
{
case n2n_ho_commit:
{
boost::thread thrd(&ho_commit_indication_handler, boost::ref(msg), boost::ref(ec));
}
break
}
};
Thanks a lot.
Keeping the threads alive is a bad idea, because it causes a call to std::terminate. You should definitively join the threads:
int main()
{
std::thread first (foo);
std::thread second (bar, 0);
first.join();
second.join();
}
An alternative is to detach the threads. However you still need to assert that the main thread lives longer (by e.g. using a mutex / condition_variable).
This excerpt from the C++11 standard is relevant here:
15.5.1 The std::terminate() function [except.terminate]
1 In some situations exception handling must be abandoned for less subtle error
handling techniques. [ Note: These situations are:
[...]
-- when the destructor or the copy assignment operator is invoked on an
object of type std::thread that refers to a joinable thread
Hence, you have to call either join or detach on threads before scope exit.
Concerning your edit: You have to store the threads in a list (or similar) and wait for every one of them before main is done. A better idea would be to use a thread pool (because this limits the total number of threads created).

QThread state when at start() call thread is still running, but after is already not

I have a GUI thread where I call write(QString text) method of another MyQThread.
MyQthread contains QMutex mutex and QList<QString> list. Here is the write() and run() methods of MyQThread:
void MyQThread::write(QString text)
{
mutex.lock();
list.append(text); //Point C
mutex.unlock();
start(); //Point D
}
void MyQThread::run()
{
mutex.lock();
while(!list.isEmpty())
{
QString text = list.takeFirst();
mutex.unlock();
...//do something
mutex.lock(); //Point A
}
mutex.unlock(); //Point B
}
For example we are at the 'point A'. After this point we are checking the list and it is empty, so we are going to 'point B'. At this moment write() is called, mutex is still locked, so GUI thread is waiting before 'point C'.
Now we are at the 'point B', after this GUI thread is unlocked and start() ('Point D') is called.
Is it possible, that at 'point D' MyQThread is still running?
In this case calling of start() do nothing. And newly added item in the list will not be processed in run() until next call of the write().
Additional information. In my case here is only one instance of MyQThread.
Yes. Although the probability of having a race condition is low, I believe there's still a chance that QThread will still be sending signals and such. Use QThread::wait before you call start() to be sure.
Edit: Agreed on the need to consider QMutexLocker. That code's going to get scary complicated pretty fast and you can't be sure that you'll remember to unlock with every exit point.
Edit2: Perhaps a QReadWriteLock might be more interesting in your case?
#alexisdm thanks for the idea. What about this solution:
class MyQThread:
public: QThread
{
...
QList<QString> list;
QMutex mutex;
QWaitCondition listNotEmpty;
}
void MyQThread::write(QString text)
{
QMutexLocker locker(&mutex);
list.append(text);
listNotEmpty.wakeAll();
}
void MyQThread::run()
{
forever
{
mutex.lock();
if(list.isEmpty())
listNotEmpty.wait(&mutex);
if(list.isEmpty())
{
mutex.unlock();
continue;
}
QString text = list.takeFirst();
mutex.unlock();
...//do something
}
}
And what about the second parameter of wait() - unsigned long time = ULONG_MAX.
It seems that in my case it will not be error, when write() method is not called for a long time and wait() will return false in run() after ULONG_MAX. And in this case I need just to wait again...
And in documentation is written:
The mutex will be returned to the same locked state.
Does it mean, that mutex will be always locked after wait() even if mutex was not locked before wait() or wait() returns false?
QThread has the methods 'isRunning' and 'isFinished'. So you could query the thread state. And sure, your thread could still be running at 'Point D'.
But you really should stop here and do some reading.
https://www.qt.io/blog/2010/06/17/youre-doing-it-wrong
and
http://woboq.com/blog/qthread-you-were-not-doing-so-wrong.html
And most certainly the Qt docs about the QMutexLocker.

Resources