Reputation: 737
I have a program like this.
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
template<int Thread>
void run()
{
for(int j=0;j<5;++j)
{
static std::mutex m;
m.lock();
cout<<"Thread "<<Thread<<" running... "<<j<<endl;
m.unlock();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
int main(int argc , char * argv [])
{
std::thread t1(run<1>);
std::thread t2(run<2>);
t1.join();
t2.join();
return 0;
}
There is a staic mutex in run()
to make sure cout
will be executed exclusively. Howerver, when I run this program with visual studio 2012, the output is:
Thread Thread 2 running... 01
running... 0
Thread 1 running... 1
Thread 2 running... 1
Thread 1 running... 2
Thread 2 running... 2
Thread 2 running... 3
Thread 1 running... 3
Thread 1 running... 4
Thread 2 running... 4
It looks the mutex does not work as expected for the first loop in run()
. Did I make anything wrong with the program?
Upvotes: 1
Views: 1765
Reputation: 27365
This is not a problem with std::mutex. Your run function declares two static mutexes, and locks one for each thread.
Consider declaring the mutex in main
and passing it as a parameter to the function, declaring it globally and locking it in the run function, or making the run function a non-template function.
Upvotes: 1
Reputation: 30035
You have a different mutex in each instantiation of your template. You'll need to make the mutex a global variable or otherwise arrange to use the same one in each function generated from the template.
Upvotes: 1
Reputation: 4606
You should place the line:
static std::mutex m;
outside the body of run()
. For example, declare it global, on the same level as run()
.
Since you are using a template, two different run()
functions are constructed, each one with its own mutex m
, invisible to each other.
Upvotes: 2
Reputation: 34538
The problem you are facing comes from the fact that your function is a template and such run<1>
and run<2>
are not the same and such do not share the same static object.
The solution would be to pass your thread number as an argument to your function.
Upvotes: 3