Reputation: 25
Here is the sample code:
#include <iostream>
#include <thread>
#include <mutex>
int value = 0;
void criticalSection(int changeValue)
{
std::mutex mtx;
std::unique_lock<std::mutex> uniqueLock(mtx);
value = changeValue;
std::cout << value << std::endl;
uniqueLock.unlock();
uniqueLock.lock();
++value;
std::cout << value << std::endl;
}
int main(int argc, char **argv)
{
std::thread t1(criticalSection, 1), t2(criticalSection, 2);
t1.join();
t2.join();
return 0;
}
My question is: what is the scope of mtx in the above code? Will each thread create a mtx within that thread? Is there any difference if I specify mtx as a global variable instead of a local variable?
I just started to learn multithread in C++. Thank you very much for your help.
Upvotes: 0
Views: 1375
Reputation: 473302
The mutex
type doesn't change C++ rules on how variables and objects work.
If you declare a non-static
variable on the stack, each call to that function will create its own version of that variable. Regardless of which thread it is. These are all separate and distinct objects.
When you lock a mutex
, you are locking that object. Other objects of the same type are unrelated to that lock.
To make a mutex
useful, both of the pieces of code trying to lock it must be locking the same object. How you accomplish this is ultimately up to your needs.
Upvotes: 1
Reputation: 122228
There are no special scoping rules for mutexes. Their scope ends on the next }
. In your code every call to criticalSection
creates a new mutex
instance. Hence, the mutex cannot possibly be used to synchronize the two threads. To do so, both threads would need to use the same mutex.
You can pass a reference to a mutex to the function:
#include <iostream>
#include <thread>
#include <mutex>
int value = 0;
void criticalSection(int changeValue,std::mutex& mtx)
{
std::unique_lock<std::mutex> uniqueLock(mtx);
//...
}
int main(int argc, char **argv)
{
std::mutex mtx;
std::thread t1(criticalSection, 1,std::ref(mtx)), t2(criticalSection, 2,std::ref(mtx));
t1.join();
t2.join();
return 0;
}
Alternatively you could use a std::atomic<int> value;
and drop the mutex when value
is the only shared state.
Upvotes: 1