大家晚上好!
我正在尝试使用Microsoft Visual Studio Express 2012在C ++中编写多线程应用程序。
我们认为“main”函数调用一个“永远”运行的线程,其任务是更新一个对象。
这是主要的:
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <cstdlib>
#include <thread>
#include <iostream>//debug only
#include <fstream> //debug only
#include "dataCollectorFTL.h"
int _tmain(int argc, _TCHAR* argv[])
{
dataCollectorFTL dataCollector1;
//Launch thread which will run forever and get the data flows
dataCollector1.runDataCollector();
while(true){
//application running
}
return 0;
}
这是班级的“.h”
#ifndef DATACOLLECTORFTL_H_INCLUDED
#define DATACOLLECTORFTL_H_INCLUDED
#include <thread>
class dataCollectorFTL {
public:
void runDataCollector();
void getData();
//constructor, destructor
dataCollectorFTL();
~dataCollectorFTL();
private:
HANDLE hProcess;
std::thread dataCollectorThread;
};
#endif // DATACOLLECTORFTL_H_INCLUDED
最后是“.cpp”
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <thread>
#include "dataCollectorFTL.h"
void dataCollectorFTL::runDataCollector(){
//lauch a non-local thread
dataCollectorThread = std::thread(&dataCollectorFTL::getData, this);
}
void dataCollectorFTL::getData(){
//some stuff
}
dataCollectorFTL::dataCollectorFTL(){
//some stuff
}
dataCollectorFTL::~dataCollectorFTL(){
dataCollectorThread.join();
}
问题在于,当我运行它时,它会给我带来这两个错误:
错误1错误C2248:'std :: thread :: operator =':无法访问类'std :: thread'中声明的私有成员c:\ users \ damien \ documents \ visual studio 2012 \ projects \ recherche \ recherche \ datacollectorftl.h 233 1 Recherche
错误4错误C2248:'std :: thread :: thread':无法访问类'std :: thread'中声明的私有成员c:\ users \ damien \ documents \ visual studio 2012 \ projects \ recherche \ recherche \ datacollectorftl.h 233 1 Recherche
为了节省时间,我可以告诉你:
如果我没有声明为该类的成员,我的程序崩溃了,因为我没有在runDataCollector()中加入()线程。并且我不想加入它,getData()是一个while(true)函数,它从另一个软件获取数据。
非常感谢您花时间阅读本文,并再次感谢您的帮助。
答案 0 :(得分:1)
我知道那是一段时间以前的事,但是我遇到了同样症状的问题,并且能够解决它,因为我的编译器(VS2012附带的VC110)对问题有更多的了解,所以也许它会帮助别人。
我想使用此结构:
struct WorkerThreadContext
{
std::thread worker;
... some other attributes ...
}
在std :: vector中。构建导致错误消息:
d:\ code \ testroom \ t2 \ t2 \ t2.cpp(16):错误C2248: 'std :: thread :: thread':无法访问在类'std :: thread'中声明的私有成员
c:\ program files(x86)\ Microsoft Visual Studio 11.0 \ vc \ include \ thread(73):请参见'std :: thread :: thread'的声明
c:\ program files(x86)\ Microsoft Visual Studio 11.0 \ vc \ include \ thread(32):请参见'std :: thread'的声明
此诊断发生在编译器生成的函数WorkerThreadContext :: WorkerThreadContext(const WorkerThreadContext&)'
中
关键部分是最后一句话-似乎编译器在为我的结构生成隐式副本构造函数时遇到问题,因此我将其更改为:
struct WorkerThreadContext
{
std::thread worker;
... other attributes ...
WorkerThreadContext() {}
// added explicit copy constructor
WorkerThreadContext(const WorkerThreadContext&) {}
};
并能够编译代码。
编辑:我几乎忘记了。编译器对此有问题的原因是,无法复制std :: thread对象(std::thread::operator=),因此编译器在构造隐式副本构造函数时遇到了问题,因为它不知道如何复制'std :: thread'对象。这也意味着,如果在其中放置显式的副本构造函数作为我编写的副本构造函数,则您的成员(包括'std :: thread'一个成员)将无效。您可以(当然应该)初始化其余结构,但是std :: thread将保持未初始化状态,因为您无法复制它。
答案 1 :(得分:0)
将函数传递给std::thread
构造函数时,需要从文件范围调用它。换句话说,如果它是一个成员函数,那么该函数必须是static
。您仍然可以传递this
- 只需告诉函数预期它。
换句话说:
将以下内容添加到类声明中:
private:
void getData(); // Moved from public!
static void myGetData(DataCollectorFTL *ftl);
写myGetData
:
void DataCollectorFTL::myGetData(DataCollectorFTL *ftl) {
ftl->getData();
} // DataCollectorFLT::myGetData(ftl)
将通话更改为std::thread()
//lauch a non-local thread
dataCollectorThread = std::thread(&myGetData, this);