boost :: scoped_lock不能使用本地静态变量?

Use*_*ser 4 c++ multithreading locking thread-safety boost-thread

我制作了以下示例程序来使用boost线程:

#pragma once
#include "boost\thread\mutex.hpp"
#include <iostream>

class ThreadWorker
{
public:
    ThreadWorker() {}
    virtual ~ThreadWorker() {}

    static void FirstCount(int threadId)
    {
        boost::mutex::scoped_lock(mutex_);
        static int i = 0;

        for(i = 1; i <= 30; i++)
        {
            std::cout << i << ": Hi from thread:  " << threadId << std::endl;
        }

    }

private:
    boost::mutex mutex_;
};
Run Code Online (Sandbox Code Playgroud)

主要课程:

// ThreadTest.cpp
#include "stdafx.h"
#include "boost\thread\thread.hpp"
#include "ThreadWorker.h"

int _tmain(int argc, _TCHAR* argv[])
{
    boost::thread thread1(&ThreadWorker::FirstCount, 1);
    boost::thread thread2(&ThreadWorker::FirstCount, 2);
    boost::thread thread3(&ThreadWorker::FirstCount, 3);

    thread1.join();
    thread2.join();
    thread3.join();

    std::string input;
    std::cout << "Press <enter> to finish...\n";
    std::getline( std::cin, input );
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我运行它时,我得到以下输出:

1: Hi from thread:  1
1: Hi from thread:  3
2: Hi from thread:  3
...
Run Code Online (Sandbox Code Playgroud)

看起来线程1首先到达那里然后是线程3.是不是scoped_lock应该阻止其他线程进入该部分代码?运行FirstCount()的第一个线程不应该完成吗?

UPDATE

我认为我的代码有一点是错误的:

boost::mutex::scoped_lock(mutex_);
Run Code Online (Sandbox Code Playgroud)

我认为应该是这样的:

boost::mutex::scoped_lock xyz(mutex_);
Run Code Online (Sandbox Code Playgroud)

一旦我这样做,它确实使关于mutex_的抱怨不是静态的.为什么它首先起作用我不确定.将mutex_更改为static会给我一个链接错误:

1> ThreadWorker.obj:错误LNK2001:未解析的外部符号"private:static class boost :: mutex ThreadWorker :: mutex_"(?mutex_ @ ThreadWorker @@ 0Vmutex @ boost @@ A)1> c:\ something\ThreadTest\Debug\ThreadTest.exe:致命错误LNK1120:1个未解析的外部

还在玩它.

Kil*_*nDS 6

你有两个错误:

首先,正如已经注意到的那样,也mutex_应该是静态的:

private:
    static boost::mutex mutex_;
Run Code Online (Sandbox Code Playgroud)

当然要在某处声明它(最好在.cpp文件中!):

boost::mutex ThreadWorker::mutex_{};
Run Code Online (Sandbox Code Playgroud)

现在,为什么编译器不抱怨?好吧,因为你实际上没有mutex_在这里用参数构造一个scoped锁:

boost::mutex::scoped_lock(mutex_);
Run Code Online (Sandbox Code Playgroud)

实际上,这不会调用您想要的构造函数,而是创建一个类型的(本地)对象mutex_,scoped_lock并由默认构造函数构造.因此,没有编译器问题.您应该将其更改为以下内容:

boost::mutex::scoped_lock l{mutex_};
Run Code Online (Sandbox Code Playgroud)

现在编译器应该开始抱怨了 mutex_