模板化函数中的静态标准::互斥锁不起作用

Static std::mutex in templated function doesn't work

本文关键字:不起作用 标准 静态 函数      更新时间:2023-10-16

我有一个这样的程序。

#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()的第一个循环中没有像预期的那样工作。我的程序有什么问题吗?

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

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

你应该放置一行:

static std::mutex m;

run()的体外。例如,将其声明为全局,与run()处于同一级别。

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

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

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

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