I was reading differences between binary semaphore and mutex (Difference between binary semaphore and mutex) and one thing that i want to verify is that when a task locks (acquires) a mutex only it can unlock (release) it. If another task tries to unlock a mutex it hasn’t locked (thus doesn’t own) then an error condition is encountered and, most importantly, the mutex is not unlocked and for that i created below code in c++14:
#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
using namespace std;
int counter;
int i;
std::mutex g_pages_mutex;
void increment()
{
std::cout<<"increment...."<<std::endl;
g_pages_mutex.lock();
bool flag = g_pages_mutex.try_lock();
std::cout<<"increment Return value is "<<flag<<std::endl;
counter++;
std::this_thread::sleep_for(5s);
}
void increment1()
{
std::this_thread::sleep_for(5s);
std::cout<<"increment1...."<<std::endl;
g_pages_mutex.unlock();
counter++;
bool flag = g_pages_mutex.try_lock();
std::cout<<"increment1 Return value is "<<flag<<std::endl;
}
int main()
{
counter = 0;
std::thread t(increment);
std::thread t1(increment1);
t.join();
t1.join();
return 0;
}
However with this example I was able to unlock mutex from thread that doesn't own that , so just want is there some understanding gap or is this issue in c++14 std::mutex ?
Calling try_lock on a std::mutex (which is not recursive) owned by the calling thread, calling unlock on a mutex not owned by the calling thread, and ending a thread while holding a mutex, all result in undefined behavior.
It might appear to succeed, it might fail and throw an exception, it might format your hard drive, it might summon nasal demons, it might time travel and correct your code for you, or it might do something else. As far as the standard is concerned, anything is permissible.
The precondition for calling unlock is holding an ownership of the mutex, according to (std)30.4.1.2:
The expression m.unlock() shall be well-formed and have the following semantics:
Requires: The calling thread shall own the mutex.
Since thread executing increment1 does not hold the ownership of the mutex it detonated undefined behavior.
From cppreference std::mutex (emphasis mine):
The behavior of a program is undefined if a mutex is destroyed while still owned by any threads, or a thread terminates while owning a mutex.
From the same site on std::mutex::try_lock and as TC points out in their answer:
If try_lock is called by a thread that already owns the mutex, the behavior is undefined.
And also std::mutex::unlock and as TC points out in their answer:
The mutex must be locked by the current thread of execution, otherwise, the behavior is undefined.
Both your functions and threads cause undefined behaviour:
increment calls lock() and then try_lock(): undefined behaviour
increment1 calls unlock() before owning the mutex: undefined behaviour
Removing the try_lock() from increment will still result in undefined behaviour if you don't call unlock() before the thread ends.
You should prefer to use a std::lock_guard, or for a simple int you could also use std::atomic
Related
Is there any potential problem in this code snippet?
#include <mutex>
#include <map>
#include <vector>
#include <thread>
constexpr int FOO_NUM = 5;
int main()
{
std::map<int, std::mutex> mp;
std::vector<std::thread> vec;
for(int i=0; i<2; i++)
{
vec.push_back(std::thread([&mp](){
std::lock_guard<std::mutex> lk(mp[FOO_NUM]); //I think there is some potential problem here, am I right?
//do something
}));
}
for(auto& thread:vec)
{
thread.join();
}
As per the document,which says that:
Inserts value_type(key, T()) if the key does not exist. This function is equivalent to return insert(std::make_pair(key, T())).first->second;
I think there is a potential problem in the aforementioned code snippet. You see this may happen:
1.the first thread created a mutex, and is locking the mutex.
2.the second thread created a new one, and the mutex created in the first thread needs to be destroyed while it's still used in the first thread.
Yes, there is a data race, but it is even more fundamental.
None of the containers in the C++ library are thread-safe, in any way. None of their operators are thread safe.
mp[FOO_NUM]
In the shown code multiple execution threads invoke map's [] operator. This is not thread-safe, the operator itself. What's contained in the map is immaterial.
the second thread created a new one, and the mutex created in the first
thread needs to be destroyed while it's still used in the first thread.
The only thing that destroys any mutex in the shown code is the map's destructor when the map itself gets destroyed when returning from main().
std::lock_guard<std::mutex> does not destroy its mutex, when the std::lock_guard gets destroyed and releases the mutex, of course. An execution thread's invocation of the map's [] operator may default-construct a new std::mutex, but there's nothing that would destroy it when the execution thread gets joined. A default-constructed value in a std::map, by its [] operator, gets destroyed only when something explicitly destroys it.
And it's the [] operator itself that's not thread safe, it has nothing to do with a mutex's construction or destruction.
operator[] of associative and unordered containers is not specified to be safe from data races if called without synchronization in multiple threads. See [container.requirements.dataraces]/1.
Therefore your code has a data race and consequently undefined behavior. Whether or not a new mutex is created doesn't matter either.
I have the namespace below which func1 and func2 will be called from diffrent threads.
#include<thread>
namespace test{
std::mutex mu;
void func1(){
std::lock_guard<mutex>lock(mu);
//the whole function needs to be protected
}
void func2() {
mu.lock();
//some code that should not be executed when func1 is executed
mu.unlock();
//some other code
}
}
is it deadlock safe to use this mutex (once with lock_guard and outside of it ) to protect these critical sections ? if not how to achieve this logic?
Yes, you can effectively mix and match different guard instances (e.g. lock_guard, unique_lock, etc...) with std::mutex in different functions. One case I run into occassionally is when I want to use std::lock_guard for most methods, but usage of std::condition_variable expects a std::unique_lock for its wait method.
To elaborate on what Oblivion said, I typically introduce a new scope block within a function so that usage of std::lock_guard is consistent. Example:
void func2() {
{ // ENTER LOCK
lock_guard<std::mutex> lck;
//some code that should not be executed when func1 is executed
} // EXIT LOCK
// some other (thread safe) code
}
The advantage of the using the above pattern is that if anything throws an exception within the critical section of code that is under a lock, the destructor of lck will still be invoked and hence, unlock the mutex.
Everything the lock_guard does is to guarantee unlock on destruction. It's a convenience to get code right when functions can take multiple paths (think of exceptions!) not a necessity. Also, it builds on the "regular" lock() and unlock() functions. In summary, it is safe.
Deadlock happens when at least two mutex are involved or the single mutex didn't unlock forever for whatever reason.
The only issue with the second function is, in case of exception the lock will not be released.
You can simply use lock_guard or anything else that gets destroyed(and unlocks the mutex at dtor) to avoid such a scenario as you did for the first function.
I was using following kind of wait/signal way to let threads inform each other.
std::condition_variable condBiz;
std::mutex mutexBar;
..
void Foo::wait()
{
std::unique_lock<std::mutex> waitPoint(mutexBar);
if (waitPoint.owns_lock())
{
condBiz.wait(waitPoint);
}
}
void Foo::signal()
{
std::unique_lock<std::mutex> waitPoint(mutexBar);
condBiz.notify_all();
}
void Foo::safeSection(std::function<void(void)> & f)
{
std::unique_lock<std::mutex> waitPoint(mutexBar);
f();
}
Then converted lock/unlock mechanism from unique_lock to lock_guard because I'm not returning unique_lock to use somewhere else(other than wait/signal) and lock_guard is said to have less overhead:
void Foo::safeSection(std::function<void(void)> & f)
{
std::lock_guard<std::mutex> waitPoint(mutexBar); // same mutex object
f();
}
and it works.
Does this work for all platforms or just looks like working for current platform? Can unique_lock and lock_guard work with each other using same mutex object?
Both std::unique_lock and std::lock_guard lock the associated mutex in the constructor and unlock it in the destructor.
std::unique_lock:
Member functions
(constructor) constructs a unique_lock, optionally locking the supplied mutex
(destructor) unlocks the associated mutex, if owned
and the same for std::lock_guard:
Member functions
(constructor) constructs a lock_guard, optionally locking the given mutex
(destructor) destructs the lock_guard object, unlocks the underlying mutex
Since both behave the same, when used as a RAII style wrapper, I see no obstacle to use them together, even with the same mutex.
It has been pointed out in the comments to your post that checking if the unique_lock is owned in Foo::wait() is pointless, because the associated mutex must be owned by the lock at that point in order for the thread to be proceeding.
Instead your condition variable should be checking some meaningful condition, and it should do so in a while loop or by using the overload of condition_variable::wait which takes a predicate as its second argument, which is required by the C++ standard to have effect as:
while (!pred()) wait(lock);
The reason for checking the predicate in a while loop is that, apart from the fact that the condition may already be satisfied so no wait is necessary, the condition variable may spuriously wake up even when not signalled to do so.
Apart from that there is no reason why the signalling thread should not use a lock_guard with respect to the associated mutex. But I am not clear what you are trying to do.
I have two use cases.
A. I want to synchronise access to a queue for two threads.
B. I want to synchronise access to a queue for two threads and use a condition variable because one of the threads will wait on content to be stored into the queue by the other thread.
For use case A I see code example using std::lock_guard<>. For use case B I see code example using std::unique_lock<>.
What is the difference between the two and which one should I use in which use case?
The difference is that you can lock and unlock a std::unique_lock. std::lock_guard will be locked only once on construction and unlocked on destruction.
So for use case B you definitely need a std::unique_lock for the condition variable. In case A it depends whether you need to relock the guard.
std::unique_lock has other features that allow it to e.g.: be constructed without locking the mutex immediately but to build the RAII wrapper (see here).
std::lock_guard also provides a convenient RAII wrapper, but cannot lock multiple mutexes safely. It can be used when you need a wrapper for a limited scope, e.g.: a member function:
class MyClass{
std::mutex my_mutex;
void member_foo() {
std::lock_guard<mutex_type> lock(this->my_mutex);
/*
block of code which needs mutual exclusion (e.g. open the same
file in multiple threads).
*/
//mutex is automatically released when lock goes out of scope
}
};
To clarify a question by chmike, by default std::lock_guard and std::unique_lock are the same.
So in the above case, you could replace std::lock_guard with std::unique_lock. However, std::unique_lock might have a tad more overhead.
Note that these days (since, C++17) one should use std::scoped_lock instead of std::lock_guard.
lock_guard and unique_lock are pretty much the same thing; lock_guard is a restricted version with a limited interface.
A lock_guard always holds a lock from its construction to its destruction. A unique_lock can be created without immediately locking, can unlock at any point in its existence, and can transfer ownership of the lock from one instance to another.
So you always use lock_guard, unless you need the capabilities of unique_lock. A condition_variable needs a unique_lock.
Use lock_guard unless you need to be able to manually unlock the mutex in between without destroying the lock.
In particular, condition_variable unlocks its mutex when going to sleep upon calls to wait. That is why a lock_guard is not sufficient here.
If you're already on C++17 or later, consider using scoped_lock as a slightly improved version of lock_guard, with the same essential capabilities.
There are certain common things between lock_guard and unique_lock and certain differences.
But in the context of the question asked, the compiler does not allow using a lock_guard in combination with a condition variable, because when a thread calls wait on a condition variable, the mutex gets unlocked automatically and when other thread/threads notify and the current thread is invoked (comes out of wait), the lock is re-acquired.
This phenomenon is against the principle of lock_guard. lock_guard can be constructed only once and destructed only once.
Hence lock_guard cannot be used in combination with a condition variable, but a unique_lock can be (because unique_lock can be locked and unlocked several times).
One missing difference is:
std::unique_lock can be moved but std::lock_guard can't be moved.
Note: Both cant be copied.
They are not really same mutexes, lock_guard<muType> has nearly the same as std::mutex, with a difference that it's lifetime ends at the end of the scope (D-tor called) so a clear definition about these two mutexes :
lock_guard<muType> has a mechanism for owning a mutex for the duration of a scoped block.
And
unique_lock<muType> is a wrapper allowing deferred locking, time-constrained attempts at locking, recursive locking, transfer of lock ownership, and use with condition variables.
Here is an example implemetation :
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <chrono>
using namespace std::chrono;
class Product{
public:
Product(int data):mdata(data){
}
virtual~Product(){
}
bool isReady(){
return flag;
}
void showData(){
std::cout<<mdata<<std::endl;
}
void read(){
std::this_thread::sleep_for(milliseconds(2000));
std::lock_guard<std::mutex> guard(mmutex);
flag = true;
std::cout<<"Data is ready"<<std::endl;
cvar.notify_one();
}
void task(){
std::unique_lock<std::mutex> lock(mmutex);
cvar.wait(lock, [&, this]() mutable throw() -> bool{ return this->isReady(); });
mdata+=1;
}
protected:
std::condition_variable cvar;
std::mutex mmutex;
int mdata;
bool flag = false;
};
int main(){
int a = 0;
Product product(a);
std::thread reading(product.read, &product);
std::thread setting(product.task, &product);
reading.join();
setting.join();
product.showData();
return 0;
}
In this example, i used the unique_lock<muType> with condition variable
As has been mentioned by others, std::unique_lock tracks the locked status of the mutex, so you can defer locking until after construction of the lock, and unlock before destruction of the lock. std::lock_guard does not permit this.
There seems no reason why the std::condition_variable wait functions should not take a lock_guard as well as a unique_lock, because whenever a wait ends (for whatever reason) the mutex is automatically reacquired so that would not cause any semantic violation. However according to the standard, to use a std::lock_guard with a condition variable you have to use a std::condition_variable_any instead of std::condition_variable.
Edit: deleted "Using the pthreads interface std::condition_variable and std::condition_variable_any should be identical". On looking at gcc's implementation:
std::condition_variable::wait(std::unique_lock&) just calls pthread_cond_wait() on the underlying pthread condition variable with respect to the mutex held by unique_lock (and so could equally do the same for lock_guard, but doesn't because the standard doesn't provide for that)
std::condition_variable_any can work with any lockable object, including one which is not a mutex lock at all (it could therefore even work with an inter-process semaphore)
I have two use cases.
A. I want to synchronise access to a queue for two threads.
B. I want to synchronise access to a queue for two threads and use a condition variable because one of the threads will wait on content to be stored into the queue by the other thread.
For use case A I see code example using std::lock_guard<>. For use case B I see code example using std::unique_lock<>.
What is the difference between the two and which one should I use in which use case?
The difference is that you can lock and unlock a std::unique_lock. std::lock_guard will be locked only once on construction and unlocked on destruction.
So for use case B you definitely need a std::unique_lock for the condition variable. In case A it depends whether you need to relock the guard.
std::unique_lock has other features that allow it to e.g.: be constructed without locking the mutex immediately but to build the RAII wrapper (see here).
std::lock_guard also provides a convenient RAII wrapper, but cannot lock multiple mutexes safely. It can be used when you need a wrapper for a limited scope, e.g.: a member function:
class MyClass{
std::mutex my_mutex;
void member_foo() {
std::lock_guard<mutex_type> lock(this->my_mutex);
/*
block of code which needs mutual exclusion (e.g. open the same
file in multiple threads).
*/
//mutex is automatically released when lock goes out of scope
}
};
To clarify a question by chmike, by default std::lock_guard and std::unique_lock are the same.
So in the above case, you could replace std::lock_guard with std::unique_lock. However, std::unique_lock might have a tad more overhead.
Note that these days (since, C++17) one should use std::scoped_lock instead of std::lock_guard.
lock_guard and unique_lock are pretty much the same thing; lock_guard is a restricted version with a limited interface.
A lock_guard always holds a lock from its construction to its destruction. A unique_lock can be created without immediately locking, can unlock at any point in its existence, and can transfer ownership of the lock from one instance to another.
So you always use lock_guard, unless you need the capabilities of unique_lock. A condition_variable needs a unique_lock.
Use lock_guard unless you need to be able to manually unlock the mutex in between without destroying the lock.
In particular, condition_variable unlocks its mutex when going to sleep upon calls to wait. That is why a lock_guard is not sufficient here.
If you're already on C++17 or later, consider using scoped_lock as a slightly improved version of lock_guard, with the same essential capabilities.
There are certain common things between lock_guard and unique_lock and certain differences.
But in the context of the question asked, the compiler does not allow using a lock_guard in combination with a condition variable, because when a thread calls wait on a condition variable, the mutex gets unlocked automatically and when other thread/threads notify and the current thread is invoked (comes out of wait), the lock is re-acquired.
This phenomenon is against the principle of lock_guard. lock_guard can be constructed only once and destructed only once.
Hence lock_guard cannot be used in combination with a condition variable, but a unique_lock can be (because unique_lock can be locked and unlocked several times).
One missing difference is:
std::unique_lock can be moved but std::lock_guard can't be moved.
Note: Both cant be copied.
They are not really same mutexes, lock_guard<muType> has nearly the same as std::mutex, with a difference that it's lifetime ends at the end of the scope (D-tor called) so a clear definition about these two mutexes :
lock_guard<muType> has a mechanism for owning a mutex for the duration of a scoped block.
And
unique_lock<muType> is a wrapper allowing deferred locking, time-constrained attempts at locking, recursive locking, transfer of lock ownership, and use with condition variables.
Here is an example implemetation :
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <chrono>
using namespace std::chrono;
class Product{
public:
Product(int data):mdata(data){
}
virtual~Product(){
}
bool isReady(){
return flag;
}
void showData(){
std::cout<<mdata<<std::endl;
}
void read(){
std::this_thread::sleep_for(milliseconds(2000));
std::lock_guard<std::mutex> guard(mmutex);
flag = true;
std::cout<<"Data is ready"<<std::endl;
cvar.notify_one();
}
void task(){
std::unique_lock<std::mutex> lock(mmutex);
cvar.wait(lock, [&, this]() mutable throw() -> bool{ return this->isReady(); });
mdata+=1;
}
protected:
std::condition_variable cvar;
std::mutex mmutex;
int mdata;
bool flag = false;
};
int main(){
int a = 0;
Product product(a);
std::thread reading(product.read, &product);
std::thread setting(product.task, &product);
reading.join();
setting.join();
product.showData();
return 0;
}
In this example, i used the unique_lock<muType> with condition variable
As has been mentioned by others, std::unique_lock tracks the locked status of the mutex, so you can defer locking until after construction of the lock, and unlock before destruction of the lock. std::lock_guard does not permit this.
There seems no reason why the std::condition_variable wait functions should not take a lock_guard as well as a unique_lock, because whenever a wait ends (for whatever reason) the mutex is automatically reacquired so that would not cause any semantic violation. However according to the standard, to use a std::lock_guard with a condition variable you have to use a std::condition_variable_any instead of std::condition_variable.
Edit: deleted "Using the pthreads interface std::condition_variable and std::condition_variable_any should be identical". On looking at gcc's implementation:
std::condition_variable::wait(std::unique_lock&) just calls pthread_cond_wait() on the underlying pthread condition variable with respect to the mutex held by unique_lock (and so could equally do the same for lock_guard, but doesn't because the standard doesn't provide for that)
std::condition_variable_any can work with any lockable object, including one which is not a mutex lock at all (it could therefore even work with an inter-process semaphore)