1

我有一个这样的程序。

#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()以确保cout将被独占执行。但是,当我使用 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

4 回答 4

3

您面临的问题来自这样一个事实,即您的函数是一个模板等等,run<1>并且run<2>不一样,并且不共享相同的静态对象。

解决方案是将您的线程号作为参数传递给您的函数。

于 2012-12-26T12:19:13.730 回答
2

您应该放置以下行:

static std::mutex m;

的身体之外run()。例如,将其声明为全局的,与run().

由于您使用的是模板,run()因此构造了两个不同的函数,每个函数都有自己的 mutex m,彼此不可见。

于 2012-12-26T12:19:38.830 回答
1

在模板的每个实例化中都有不同的互斥锁。您需要使互斥体成为全局变量,或者安排在从模板生成的每个函数中使用相同的变量。

于 2012-12-26T12:19:50.937 回答
1

这不是 std::mutex 的问题。您的 run 函数声明了两个静态互斥锁,并为每个线程锁定一个。

考虑在其中声明互斥体main并将其作为参数传递给函数,全局声明它并将其锁定在 run 函数中,或者使 run 函数成为非模板函数。

于 2012-12-26T12:21:51.170 回答