我有这样的程序。
#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;
}
run()
中有一个staic互斥锁,以确保cout
将独占执行。 Howerver,当我用visual studio 2012运行这个程序时,输出是:
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
看起来互斥锁在run()
中的第一个循环中没有按预期工作。我对这个程序有什么不妥吗?
答案 0 :(得分:3)
您遇到的问题来自于您的函数是一个模板,而run<1>
和run<2>
不相同,因此不会共享相同的静态对象。
解决方案是将您的线程号作为参数传递给您的函数。
答案 1 :(得分:2)
你应该放行:
static std::mutex m;
在run()
的正文之外。例如,将其声明为全局,与run()
处于同一级别。
由于您使用的是模板,因此构建了两个不同的run()
函数,每个函数都有自己的互斥m
,彼此不可见。
答案 2 :(得分:1)
模板的每个实例化中都有一个不同的互斥锁。您需要将互斥锁变为全局变量,或者在模板生成的每个函数中使用相同的变量。
答案 3 :(得分:1)
这不是std :: mutex的问题。您的run函数声明了两个静态互斥锁,并为每个线程锁定一个。
考虑在main
中声明互斥体并将其作为参数传递给函数,将其全局声明并将其锁定在run函数中,或者使run函数成为非模板函数。