我制作了以下示例程序来使用增强线程:
#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_;
};
主要课程:
// 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;
}
当我运行时,我得到以下输出:
1: Hi from thread: 1
1: Hi from thread: 3
2: Hi from thread: 3
...
看起来线程1首先到达那里然后是线程3.是不是scoped_lock应该阻止其他线程进入该段代码?运行FirstCount()的第一个线程不应该完成吗?
更新
我认为我的代码有一个问题就是这一行:
boost::mutex::scoped_lock(mutex_);
我认为应该是这样的:
boost::mutex::scoped_lock xyz(mutex_);
一旦我这样做,它确实使关于mutex_的抱怨不是静态的。为什么它首先起作用我不确定。将mutex_更改为static会给我一个链接错误:
1&gt; ThreadWorker.obj:错误LNK2001:未解析的外部符号 “private:static class boost :: mutex ThreadWorker :: mutex_” (?mutex_ @ ThreadWorker @@ 0Vmutex @升压@@ A) 1&gt; c:\ something \ ThreadTest \ Debug \ ThreadTest.exe:致命错误LNK1120: 1个未解决的外部
还在玩它。
答案 0 :(得分:6)
您有两个错误:
首先,正如已经注意到的那样,mutex_
也应该是静态的:
private:
static boost::mutex mutex_;
当然要在某处(最好是.cpp文件中声明!):
boost::mutex ThreadWorker::mutex_{};
现在,编译器为什么不抱怨?好吧,因为你实际上没有在这里构造一个带参数mutex_
的范围锁:
boost::mutex::scoped_lock(mutex_);
实际上这不会调用你想要的构造函数,而是创建一个类型为mutex_
的(本地)对象scoped_lock
,并由默认构造函数构造。因此,没有编译器问题。您应该将其更改为以下内容:
boost::mutex::scoped_lock l{mutex_};
现在编译器应该开始抱怨mutex_
答案 1 :(得分:3)
你有三个独立的对象,它们都不能看到对方的互斥对象,因为该成员是在每个对象中创建的。
也许你的意思是让mutex_静态?
编辑:如果我使互斥锁静态并从i变量中删除静态,那么它似乎工作,因为我猜你的意思。似乎是这样的事情:每个线程立即进入循环,并且由于互斥锁不是静态的,因此不会彼此锁定。当他们将所有输出都输出到控制台时(我不记得在写入cout时是否存在互斥)并且我得到增量,他们都将静态i视为30并退出。
编辑2:不,仍然不正确,因为在某些运行中仍然存在散布的值。
编辑3:它编译的原因是你的scoped_lock是一个临时的,它似乎让编译器抛弃了mutex_应该是静态的事实。请尝试使用以下代码:
#include <iostream>
#include "boost\thread\mutex.hpp"
#include "boost\thread\thread.hpp"
class ThreadWorker
{
public:
ThreadWorker() {}
virtual ~ThreadWorker() {}
static void FirstCount(int threadId)
{
// Created object f here rather than temprary
boost::mutex::scoped_lock f(mutex_);
int i = 0; // Not static
for(i = 1; i <= 30; i++)
{
std::cout << i << ": Hi from thread: " << threadId << std::endl;
}
}
private:
static boost::mutex mutex_; // Static
};
// Storage for static
boost::mutex ThreadWorker::mutex_;
int main(int argc, char* 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;
}
答案 2 :(得分:0)
此代码是否也使用相同的编译器进行编译?
您能看到此代码的问题吗?尝试在不编译的情况下发现问题。
class C { public: static int f () { return i; } int i; }; int main() { return C::f(); }
更新: 我刚看了你的更新。
class C { public: static int f () { return i; } static int i; }; int C::i = whatever; int main() { return C::f(); }
答案 3 :(得分:0)
将我的代码更改为:
ThreadWorker.h:
#pragma once
#include "boost\thread\mutex.hpp"
#include <iostream>
class ThreadWorker
{
public:
ThreadWorker();
virtual ~ThreadWorker();
static void FirstCount(int threadId);
private:
static boost::mutex mutex_;
};
ThreadWorker.cpp:
#include "stdafx.h"
#include "ThreadWorker.h"
boost::mutex ThreadWorker::mutex_;
ThreadWorker::ThreadWorker()
{
}
ThreadWorker::~ThreadWorker()
{
}
void ThreadWorker::FirstCount(int threadId)
{
boost::mutex::scoped_lock xyz(mutex_);
static int i = 0;
for(i = 1; i <= 30; i++)
{
std::cout << i << ": Hi from thread: " << threadId << std::endl;
}
}
ThreadTest.cpp:
// ThreadTest.cpp : Defines the entry point for the console application.
//
#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;
}
我做的更改是1.分隔标题和cpp文件(我最初只是为了使我的帖子更紧凑)2。给scoped_lock变量一个标识符和3.使互斥锁静态。
它现在按预期工作,从每个线程顺序打印30行。令我感到困惑的是为什么之前编译的代码(因为tinman也能够编译我的原始代码)。