I have a object and all its function should be executed in sequential order.
I know it is possible to do that with a mutex like
#include <mutex>
class myClass {
private:
std::mutex mtx;
public:
void exampleMethod();
};
void myClass::exampleMethod() {
std::unique_lock<std::mutex> lck (mtx); // lock mutex until end of scope
// do some stuff
}
but with this technique a deadlock occurs after calling an other mutex locked method within exampleMethod.
so i'm searching for a better resolution.
the default std::atomic access is sequentially consistent, so its not possible to read an write to this object at the same time, but now when i access my object and call a method, is the whole function call also atomic or more something like
object* obj = atomicObj.load(); // read atomic
obj.doSomething(); // call method from non atomic object;
if yes is there a better way than locking the most functions with a mutex ?
Stop and think about when you actually need to lock a mutex. If you have some helper function that is called within many other functions, it probably shouldn't try to lock the mutex, because the caller already will have.
If in some contexts it is not called by another member function, and so does need to take a lock, provide a wrapper function that actually does that. It is not uncommon to have 2 versions of member functions, a public foo() and a private fooNoLock(), where:
public:
void foo() {
std::lock_guard<std::mutex> l(mtx);
fooNoLock();
}
private:
void fooNoLock() {
// do stuff that operates on some shared resource...
}
In my experience, recursive mutexes are a code smell that indicate the author hasn't really got their head around the way the functions are used - not always wrong, but when I see one I get suspicious.
As for atomic operations, they can really only be applied for small arithmetic operations, say incrementing an integer, or swapping 2 pointers. These operations are not automatically atomic, but when you use atomic operations, these are the sorts of things they can be used for. You certainly can't have any reasonable expectations about 2 separate operations on a single atomic object. Anything could happen in between the operations.
You could use a std::recursive_mutex instead. This will allow a thread that already owns to mutex to reacquire it without blocking. However, if another thread tries to acquire the lock it will block.
As #BoBTFish properly indicated, it is better to separate your class's public interface, which member functions acquire non-recursive lock and then call private methods which don't. Your code must then assume a lock is always held when a private method is run.
To be safe on this, you may add a reference to std::unique_lock<std::mutex> to each of the method that requires the lock to be held.
Thus, even if you happen to call one private method from another, you would need to make sure a mutex is locked before execution:
class myClass
{
std::mutex mtx;
//
void i_exampleMethod(std::unique_lock<std::mutex> &)
{
// execute method
}
public:
void exampleMethod()
{
std::unique_lock<std::mutex> lock(mtx);
i_exampleMethod(lock);
}
};
Related
I'm learning about mutex and threading right now. I was wondering if there's anything dangerous or inherently wrong with automating mutex with a class like this:
class AutoMutex
{
private:
std::mutex& m_Mutex;
public:
AutoMutex(std::mutex& m) : m_Mutex(m)
{
m_Mutex.lock();
}
~AutoMutex()
{
m_Mutex.unlock();
}
};
And then, of course, you would use it like this:
void SomeThreadedFunc()
{
AutoMutex m(Mutex); // With 'Mutex' being some global mutex.
// Do stuff
}
The idea is that, on construction of an AutoMutex object, it locks the mutex. Then, when it goes out of scope, the destructor automatically unlocks it.
You could even just put it in scopes if you don't need it for an entire function. Like this:
void SomeFunc()
{
// Do stuff
{
AutoMutex m(Mutex);
// Do race condition stuff.
}
// Do other stuff
}
Is this okay? I don't personally see anything wrong with it, but as I'm not the most experienced, I feel there's something I may be missing.
It's safe to use a RAII wrapper, and in fact safer than using mutex member functions directly, but it's also unnecessary to write since standard library already provides this. It's called std::lock_guard.
However, your implementation isn't entirely safe, because it's copyable, and a copy will attempt to re-unlock the mutex which will lead to undefined behaviour. std::lock_guard resolves this issue by being non-copyable.
There's also std::unique_lock which is very similar, but allows things such as releasing the lock within the lifetime. std::scoped_lock should be used if you need to lock multiple mutexes. Using multiple lock guard may lead to deadlock. std::scoped_lock is also fine to use with a single mutex, so you can replace all uses of lock guard with it.
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.
Situation: I have two methods: method1 loads values of config; method2 returns the values of loaded config. both method maybe called by different threads.
Issue: I want to use one mutex to lock/unlock two methods. so when method1 is locked, when method2 is called it should also be locked. I get confused when I read about mutex, when they say that i locks the region of the code until unlock is called.
Question: When I lock method1, am I also locking method2?
Expectation: what I want to happen is method2 to be called when method1 is updating the config data that will be returned by method2.
Sample Code:
void Class::method1() {
pthread_mutex_lock(mutex1);
string1 = "a value";
pthread_mutex_unlock(mutex1);
};
void Class::method2(string& aString) {
pthread_mutex_lock(mutex1);
aString = string1;
pthread_mutex_unlock(mutex1);
return;
};
Yes, you can (and should) use the same mutex. Though it's more preferable to acquire it with RAII (you could use std::lock_guard if your mutex was std::mutex or a wrapper around pthread_mutex_t implementing lock() and unlock()):
void Class::method1() {
std::lock_guard<std::mutex> lock(mutex1);
...
}
This way not only you can place return statements anywhere in the code, but also you achieve exception safety (mutex will be unlocked if the method throws an exception).
This is precisely how mutexes should be used -- to protect data from being accessed in one thread while another thread is, or might be, modifying it. Just fix the bug in method2 (preferably by acquiring the mutex using RAII and letting the mutex holder's destructor unlock the mutex after the return value is copied).
I am very confused about the difference between a lock and mutex. In Boost docs, it says,
Lock Types
Class template lock_guard
Class template unique_lock
Class template shared_lock
Class template upgrade_lock
Class template upgrade_to_unique_lock
Mutex-specific class scoped_try_lock
Mutex Types
Class mutex
Typedef try_mutex
Class timed_mutex
Class recursive_mutex
Typedef recursive_try_mutex
Class recursive_timed_mutex
Class shared_mutex
In another article, I see functions like this,
boost::shared_mutex _access;
void reader()
{
boost::shared_lock< boost::shared_mutex > lock(_access);
// do work here, without anyone having exclusive access
}
void conditional_writer()
{
boost::upgrade_lock< boost::shared_mutex > lock(_access);
// do work here, without anyone having exclusive access
if (something) {
boost::upgrade_to_unique_lock< boost::shared_mutex > uniqueLock(lock);
// do work here, but now you have exclusive access
}
// do more work here, without anyone having exclusive access
}
Updated questions
Can anyone offer some clarification between the "mutex" and "lock"?
Is it necessary to create a shared_lock for a shared_mutex?
What happen if I create a unique_lock for a shared_mutex?
Or if I create a shared_lock for a mutex, does it mean the mutex can
not be shared among multiple threads?
A mutex is a synchronization object. You acquire a lock on a mutex at the beginning of a section of code, and release it at the end, in order to ensure that no other thread is accessing the same data at the same time. A mutex typically has a lifetime equal to that of the data it is protecting, and that one mutex is accessed by multiple threads.
A lock object is an object that encapsulates that lock. When the object is constructed it acquires the lock on the mutex. When it is destructed the lock is released. You typically create a new lock object for every access to the shared data.
A mutex is an object which can be locked. A lock is the object which
maintains the lock. To create a lock, you need to pass it a mutex.
Locks can provide mutual exclusion but not condition synchronization.Unlike a semaphore, a lock has an owner, and ownership plays an important
role in the behavior of a lock
example -
class lockableObject { public void F() {
mutex.lock(); ...; mutex.unlock();
}
public void G() {
mutex.lock(); ...; F(); ...; mutex.unlock();
}
private mutexLock mutex; }
// method G() calls method F()
Lock mutex in class lockableObject is used to turn methods F() and G() into critical sections. Thus, only one thread at a time can execute inside a method of a lockableObject. When a thread calls method G(), the mutex is locked. When method G() calls method F(), mutex.lock() is executed in F(), but the calling thread is not blocked since it already owns mutex. If mutex were a binary semaphore instead of a lock, the call from G() to F() would block the calling thread when mutex.P() was executed in F(). (Recall that comple- tions of P() and V() operations on a binary semaphore must alternate.) This would create a deadlock since no other threads would be able execute inside F() or G().
These are differences between locks and binary semaphores:
1 For a binary semaphore,if two calls are made toP()without any intervening call to V(), the second call will block. But a thread that owns a lock and requests ownership again is not blocked. (Beware of the fact that locks are not always recursive, so check the documentation before using a lock.)
2 The owner for successive calls to lock() and unlock() must be the same thread. But successive calls to P () and V () can be made by different threads.
Not sure if this is a style question, or something that has a hard rule...
If I want to keep the public method interface as const as possible, but make the object thread safe, should I use mutable mutexes? In general, is this good style, or should a non-const method interface be preferred? Please justify your view.
The hidden question is: where do you put the mutex protecting your class?
As a summary, let's say you want to read the content of an object which is protected by a mutex.
The "read" method should be semantically "const" because it does not change the object itself. But to read the value, you need to lock a mutex, extract the value, and then unlock the mutex, meaning the mutex itself must be modified, meaning the mutex itself can't be "const".
If the mutex is external
Then everything's ok. The object can be "const", and the mutex don't need to be:
Mutex mutex ;
int foo(const Object & object)
{
Lock<Mutex> lock(mutex) ;
return object.read() ;
}
IMHO, this is a bad solution, because anyone could reuse the mutex to protect something else. Including you. In fact, you will betray yourself because, if your code is complex enough, you'll just be confused about what this or that mutex is exactly protecting.
I know: I was victim of that problem.
If the mutex is internal
For encapsulation purposes, you should put the mutex as near as possible from the object it's protecting.
Usually, you'll write a class with a mutex inside. But sooner or later, you'll need to protect some complex STL structure, or whatever thing written by another without mutex inside (which is a good thing).
A good way to do this is to derive the original object with an inheriting template adding the mutex feature:
template <typename T>
class Mutexed : public T
{
public :
Mutexed() : T() {}
// etc.
void lock() { this->m_mutex.lock() ; }
void unlock() { this->m_mutex.unlock() ; } ;
private :
Mutex m_mutex ;
}
This way, you can write:
int foo(const Mutexed<Object> & object)
{
Lock<Mutexed<Object> > lock(object) ;
return object.read() ;
}
The problem is that it won't work because object is const, and the lock object is calling the non-const lock and unlock methods.
The Dilemma
If you believe const is limited to bitwise const objects, then you're screwed, and must go back to the "external mutex solution".
The solution is to admit const is more a semantic qualifier (as is volatile when used as a method qualifier of classes). You are hiding the fact the class is not fully const but still make sure provide an implementation that keeps the promise that the meaningful parts of the class won't be changed when calling a const method.
You must then declare your mutex mutable, and the lock/unlock methods const:
template <typename T>
class Mutexed : public T
{
public :
Mutexed() : T() {}
// etc.
void lock() const { this->m_mutex.lock() ; }
void unlock() const { this->m_mutex.unlock() ; } ;
private :
mutable Mutex m_mutex ;
}
The internal mutex solution is a good one IMHO: Having to objects declared one near the other in one hand, and having them both aggregated in a wrapper in the other hand, is the same thing in the end.
But the aggregation has the following pros:
It's more natural (you lock the object before accessing it)
One object, one mutex. As the code style forces you to follow this pattern, it decreases deadlock risks because one mutex will protect one object only (and not multiple objects you won't really remember), and one object will be protected by one mutex only (and not by multiple mutex that needs to be locked in the right order)
The mutexed class above can be used for any class
So, keep your mutex as near as possible to the mutexed object (e.g. using the Mutexed construct above), and go for the mutable qualifier for the mutex.
Edit 2013-01-04
Apparently, Herb Sutter have the same viewpoint: His presentation about the "new" meanings of const and mutable in C++11 is very enlightening:
http://herbsutter.com/2013/01/01/video-you-dont-know-const-and-mutable/
[Answer edited]
Basically using const methods with mutable mutexes is a good idea (don't return references by the way, make sure to return by value), at least to indicate they do not modify the object. Mutexes should not be const, it would be a shameless lie to define lock/unlock methods as const...
Actually this (and memoization) are the only fair uses I see of the mutable keyword.
You could also use a mutex which is external to your object: arrange for all your methods to be reentrant, and have the user manage the lock herself : { lock locker(the_mutex); obj.foo(); } is not that hard to type, and
{
lock locker(the_mutex);
obj.foo();
obj.bar(42);
...
}
has the advantage it doesn't require two mutex locks (and you are guaranteed the state of the object did not change).