Suppose I have a function that tries to protect a global counter using this code:
static MyCriticalSectionWrapper lock;
lock.Enter();
counter = ++m_counter;
lock.Leave();
IS there a chance that two threads will invoke the lock's constructor? What is the safe way to achieve this goal?
The creation of the lock object itself is not thread safe. Depending on the compiler, you might have multiple independent lock objects created if multiple threads enter the function at (nearly) the same time.
The solution to this problem is to use:
OS guaranteed one time intialization (for the lock object)
Double-checked locking (Assuming it is safe for your particular case)
A thread safe singleton for the lock object
For your specific example, you may be able to use a thread safe interlocked (e.g., the InterlockedIncrement() function for Windows) operation for the increment and avoid locking altogether
Constructor invoke can be implementation and/or execution environment dependent, but this isn't a scoped_lock so not an issue.
Main operation is properly guarded against multi thread access I think.
(You know, global for global, function static for function static. That lock variable must be defined in the same scope with the guarded object.)
Original sample code:
static MyCriticalSectionWrapper lock;
lock.Enter();
counter = ++m_counter;
lock.Leave();
I realize that the counter code is probably just a placeholder, however if it is actually what you trying to do you could use the Windows function "InterlockedIncrement()" to accomplish this.
Example:
// atomic increment for thread safety
InterlockedIncrement(&m_counter);
counter = m_counter;
That depends on your lock implementation.
Related
I am learning about C++ threading. I have a class called Shape which has member variables called mWidth and mHeight. There's a member function called Shape::setWH(int newWidth,int newHeight) which modifies mWidth and mHeight. Multiple threads can perform this operation on same object right? so I can say its not thread safe and use std::mutex to lock the operation.
If a class has bunch of member functions which modifies member variables. Can we say that none of them are thread safe?
Yes. If not stated otherwise you have to assume that methods are not thread-safe. Making each and every single method thread safe would be no good, because the caller needs to be in control of synchronization when they want more coarse grained synchronization (eg lock a mutex for many calls rather than every single call).
Types have to be assumed to be not thread-safe unless their methods are explicitly stated to be thread safe. Baking in synchronisation into each single method would be inefficient, because that would mean that the caller has no control over how to use them in a thread safe way.
Suppose the caller writes a tight loop, then they want to lock a mutex only once not in every iteration:
std::lock_guard<std::mutex> lock(mymutex);
for (int i=0;i <10000; ++i) {
foo.setSomething(i);
}
Or suppose a user is completely sure that no synchronization is needed, then locking a mutex anyhow is unecessary overhead.
It is completely ok to not provide the thread-safety you are worried about. As long as you do not claim that something would be thread-safe the caller should be aware that it isnt and that they need to use synchronization. What you should care about is that const should not just be logical constness but actual constness. For example:
struct foo {
int get42() const {
++calls;
return 42;
}
private:
mutable int calls = 0;
};
In a single-threaded context this is completely fine. From outside there is no way to see that calling foo::get42 changed internal state. The method does not modify "logical state", it does however modify the binary state of the object. Avoid that and document when a non-const method is thread-safe. Then the caller should be ready to use your type in a thread-safe way.
Please consider this classical approach, I have simplified it to highlight the exact question:
#include <iostream>
#include <mutex>
using namespace std;
class Test
{
public:
void modify()
{
std::lock_guard<std::mutex> guard(m_);
// modify data
}
private:
/// some private data
std::mutex m_;
};
This is the classical approach of using std::mutex to avoid data races.
The question is why are we keeping an extra std::mutex in our class? Why can't we declare it every time before the declaration of std::lock_guard like this?
void modify()
{
std::mutex m_;
std::lock_guard<std::mutex> guard(m_);
// modify data
}
Lets say two threads are calling modify in parallel. So each thread gets its own, new mutex. So the guard has no effect as each guard is locking a different mutex. The resource you are trying to protect from race-conditions will be exposed.
The misunderstanding comes from what the mutex is and what the lock_guard is good for.
A mutex is an object that is shared among different threads, and each thread can lock and release the mutex. That's how synchronization among different threads works. So you can work with m_.lock() and m_.unlock() as well, yet you have to be very careful that all code paths (including exceptional exits) in your function actually unlocks the mutex.
To avoid the pitfall of missing unlocks, a lock_guard is a wrapper object which locks the mutex at wrapper object creation and unlocks it at wrapper object destruction. Since the wrapper object is an object with automatic storage duration, you will never miss an unlock - that's why.
A local mutex does not make sense, as it would be local and not a shared ressource. A local lock_guard perfectly makes sense, as the autmoatic storage duration prevents missing locks / unlocks.
Hope it helps.
This all depends on the context of what you want to prevent from being executed in parallel.
A mutex will work when multiple threads try to access the same mutex object. So when 2 threads try to access and acquire the lock of a mutex object, only one of them will succeed.
Now in your second example, if two threads call modify(), each thread will have its own instance of that mutex, so nothing will stop them from running that function in parallel as if there's no mutex.
So to answer your question: It depends on the context. The mission of the design is to ensure that all threads that should not be executed in parallel will hit the same mutex object at the critical part.
Synchronization of threads involves checking if there is another thread executing the critical section. A mutex is the objects that holds the state for us to check if it was "locked" by a thread. lock_guard on the other hand is a wrapper that locks the mutex on initialization and unlocks it during destruction.
Having realized that, it should be clearer why there has to be only one instance of the mutex that all lock_guards need access to - they need to check if it's clear to enter the critical section against the same object. In the second snippet of your question each function call creates a separate mutex that is seen and accessible only in its local context.
You need a mutex at class level. Otherwise, each thread has a mutex for itself, and therefore the mutex has no effect.
If for some reason you don't want your mutex to be stored in a class attribute, you could use a static mutex as shown below.
void modify()
{
static std::mutex myMutex;
std::lock_guard<std::mutex> guard(myMutex);
// modify data
}
Note that here there is only 1 mutex for all the class instances. If the mutex is stored in an attribute, you would have one mutex per class instance. Depending on your needs, you might prefer one solution or the other.
It may sound dummy but,Am sort of confused, I have gone through this question,when looking into it we both where in the same situation it seems, I have to make my map as static so it will be common to all instances that will be created in separate threads and I want to synchronize the functions that gonna act on my map, so i thought of making a std::mutex as static in my class like what was suggested as an answer in the given link.. in this case will there be any race-condition occur for acquiring and locking the mutex itself? is there any better way we can synchronize the functions on static map using mutex
Does Making std::mutex as static creates race-condition for the mutex
itself
No, a Mutex isn't vulnerable to race-conditions. And as for initializing it as static, you are safe.
$6.7: 4: Dynamic initialization of a block-scope variable with static storage duration ([basic.stc.static]) or thread storage
duration ([basic.stc.thread]) 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
You said:
i thought of making a std::mutex as static in my class like what was
suggested as an answer in the given link.
Do that if you are trying to protect static class member variables as well. Otherwise, make it a mutable member. The fact that you said the map will be globally initialized as static is okay, since the mutex as a member variable, will follow suite.
class Map{
public:
Map(...){}
std::size_t size() const{
std::lock_guard<std::mutex> lck(m_m);
return m_size;
}
iterator add(....) {
std::lock_guard<std::mutex> lck(m_m);
....
return your_iterator;
}
...etc
private:
mutable std::mutex m_m; //FREE ADVICE: Use a std::recursive_mutex instead
...others
};
Now:
//Somewhere at global scope:
Map mp(... ...);
// NOTES
// 1. `mp` will be initialized in a thread safe way by the runtime.
// 2. Since you've protected all Read or Write member functions of the class `Map`,
// you are safe to call it from any function and from any thread
No.
Mutexes (and other synchronisation primitives) are implemented using support from the operating system. That's the only way that they can do their job.
A direct corollorary of their ability to perform this job is that they are themselves not prone to race conditions — locking and unlocking operations on mutexes are atomic.
Otherwise, they wouldn't be much use! Every time you used a mutex, you'd have to protect it with another mutex, then protect that mutex with another mutex, and so on and so forth until you had an infinite number of mutexes, none of them actually achieving anything of any use at all. :)
The std::mutex object having static storage duration doesn't change this in any way. Presumably you were thinking of function-static variables (that, assuming they're not already immune to race conditions, must be synchronised because they may be accessed concurrently by different threads; but still, ideally you wouldn't use them at all because they make functions not be re-entrant).
I am new to multi thread programming, yet I am studying a big project by someone else. In the code he has a singleton class and it has some public member variable and a member mutex. He used this singleton in different threads like:
singleton::instance()->mutex.lock();
singleton::instance()->value = getval();
singleton::instance()->mutex.release();
Is this the safe way to do it?
If not what is the proper way of read/write the value in singleton?
No it is not safe to do so.
The problem is that the mutex is handed out to the user. There is no guarantee that this lock will be released. For example, what happens if getval() would throw an exception ?
The proper way to do so would be to embed mutex use inside the API of your singleton. For example:
void singleton::setvalue(int val) { // example supposing value is an int
std::lock_guard<std::mutex> mylck (mutex);
value = val;
}
In this example, a local std::lock_guard is used. This object locks the mutex and unlocks it on destruction. This makes sure that in any case the mutex will be unlocked, whenever function returns and even if an exception would be thrown.
Note: If all you are doing is getting a variable like return variable; then it is safe to do even without the lock.
About the code. Assuming the lock is implemented correctly then it is safe to do anything before release is called
I am new to multi-threading programming, and confused about how Mutex works. In the Boost::Thread manual, it states:
Mutexes guarantee that only one thread can lock a given mutex. If a code section is surrounded by a mutex locking and unlocking, it's guaranteed that only a thread at a time executes that section of code. When that thread unlocks the mutex, other threads can enter to that code region:
My understanding is that Mutex is used to protect a section of code from being executed by multiple threads at the same time, NOT protect the memory address of a variable. It's hard for me to grasp the concept, what happen if I have 2 different functions trying to write to the same memory address.
Is there something like this in Boost library:
lock a memory address of a variable, e.g., double x, lock (x); So
that other threads with a different function can not write to x.
do something with x, e.g., x = x + rand();
unlock (x)
Thanks.
The mutex itself only ensures that only one thread of execution can lock the mutex at any given time. It's up to you to ensure that modification of the associated variable happens only while the mutex is locked.
C++ does give you a way to do that a little more easily than in something like C. In C, it's pretty much up to you to write the code correctly, ensuring that anywhere you modify the variable, you first lock the mutex (and, of course, unlock it when you're done).
In C++, it's pretty easy to encapsulate it all into a class with some operator overloading:
class protected_int {
int value; // this is the value we're going to share between threads
mutex m;
public:
operator int() { return value; } // we'll assume no lock needed to read
protected_int &operator=(int new_value) {
lock(m);
value = new_value;
unlock(m);
return *this;
}
};
Obviously I'm simplifying that a lot (to the point that it's probably useless as it stands), but hopefully you get the idea, which is that most of the code just treats the protected_int object as if it were a normal variable.
When you do that, however, the mutex is automatically locked every time you assign a value to it, and unlocked immediately thereafter. Of course, that's pretty much the simplest possible case -- in many cases, you need to do something like lock the mutex, modify two (or more) variables in unison, then unlock. Regardless of the complexity, however, the idea remains that you centralize all the code that does the modification in one place, so you don't have to worry about locking the mutex in the rest of the code. Where you do have two or more variables together like that, you generally will have to lock the mutex to read, not just to write -- otherwise you can easily get an incorrect value where one of the variables has been modified but the other hasn't.
No, there is nothing in boost(or elsewhere) that will lock memory like that.
You have to protect the code that access the memory you want protected.
what happen if I have 2 different functions trying to write to the same
memory address.
Assuming you mean 2 functions executing in different threads, both functions should lock the same mutex, so only one of the threads can write to the variable at a given time.
Any other code that accesses (either reads or writes) the same variable will also have to lock the same mutex, failure to do so will result in indeterministic behavior.
It is possible to do non-blocking atomic operations on certain types using Boost.Atomic. These operations are non-blocking and generally much faster than a mutex. For example, to add something atomically you can do:
boost::atomic<int> n = 10;
n.fetch_add(5, boost:memory_order_acq_rel);
This code atomically adds 5 to n.
In order to protect a memory address shared by multiple threads in two different functions, both functions have to use the same mutex ... otherwise you will run into a scenario where threads in either function can indiscriminately access the same "protected" memory region.
So boost::mutex works just fine for the scenario you describe, but you just have to make sure that for a given resource you're protecting, all paths to that resource lock the exact same instance of the boost::mutex object.
I think the detail you're missing is that a "code section" is an arbitrary section of code. It can be two functions, half a function, a single line, or whatever.
So the portions of your 2 different functions that hold the same mutex when they access the shared data, are "a code section surrounded by a mutex locking and unlocking" so therefore "it's guaranteed that only a thread at a time executes that section of code".
Also, this is explaining one property of mutexes. It is not claiming this is the only property they have.
Your understanding is correct with respect to mutexes. They protect the section of code between the locking and unlocking.
As per what happens when two threads write to the same location of memory, they are serialized. One thread writes its value, the other thread writes to it. The problem with this is that you don't know which thread will write first (or last), so the code is not deterministic.
Finally, to protect a variable itself, you can find a near concept in atomic variables. Atomic variables are variables that are protected by either the compiler or the hardware, and can be modified atomically. That is, the three phases you comment (read, modify, write) happen atomically. Take a look at Boost atomic_count.