模板化函数中的静态std :: mutex不起作用

时间:2012-12-26 12:13:02

标签: c++ multithreading c++11

我有这样的程序。

#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()中的第一个循环中没有按预期工作。我对这个程序有什么不妥吗?

4 个答案:

答案 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函数成为非模板函数。