std::mutex 和 condition_variable 无法访问类内的私有成员
std::mutex and condition_variable cannot access private member inside class
我已经做了一些谷歌搜索,并在堆栈溢出上看到了关于这个问题的类似问题,但很难理解处理它的原因/解决方案。给定在 ThreadPool.hpp 中声明的以下类,我收到以下 2 个错误:
错误 1 错误 C2248:"std::mutex::mutex":无法访问在类"std::mutex"中声明的私有成员 C:\用户\jesse\文档\学校\夏季学期 2012\并发处理\项目 2\ultra_grep v2\ultra_grep\threadpool.hpp 39 1 ultra_grep2
错误2 错误 C2248:"std::condition_variable::condition_variable":无法访问类"std::condition_variable"中声明的私有成员 C:\用户\杰西\文档\学校\2012 年夏季学期\并发处理\项目 2\ultra_grep v2\ultra_grep\threadpool.hpp 39 1 ultra_grep2
class ThreadPool
{
private:
std::queue<std::string> _consoleTasks;
std::queue<std::tr2::sys::path> _tasks;
std::map<std::string, std::vector<GrepMatch>> _grepMatches;
int _nThreads, _fileMatches, _totalMatches, _workingThreads;
std::vector<thread> _threads;
Arguments _args;
std::mutex _taskMutex, _wakeMutex, _consoleMutex, _threadCountMutex;
std::condition_variable _wakeCondition;
public:
ThreadPool( int threads, Arguments args );
~ThreadPool() {};
void GrepFunc();
void ConsoleFunc();
void SearchFile( std::string );
void SearchFileVerbose( std::string );
void DisplayGrepResults();
queue<std::tr2::sys::path> Tasks() { return _tasks; }
};
以及 ThreadPool 内部实现的代码.cpp:
#include "ThreadPool.hpp"
using namespace std;
namespace fs = std::tr2::sys;
ThreadPool::ThreadPool( int threads, Arguments args )
: _nThreads( threads ), _args( args ), _fileMatches( 0 ), _totalMatches( 0 ), _workingThreads( 0 )
{
for( int i = 0; i < _nThreads; ++i )
{
_threads.push_back( thread( &ThreadPool::GrepFunc, this ) );
_tasks.push( args.root() );
++_workingThreads;
_wakeCondition.notify_one();
}
for( auto& t : _threads )
{
t.join();
}
DisplayGrepResults();
}
void ThreadPool::GrepFunc()
{
// implement a barrier()
while( !_workingThreads )
{
{ unique_lock<mutex> lk( _wakeMutex );
_wakeCondition.wait( lk ); }
while( !_tasks.empty() )
{
fs::path task;
bool gotTask = false;
{
lock_guard<mutex> tl( _taskMutex );
if( !_tasks.empty() )
{
{ lock_guard<mutex> tc( _threadCountMutex );
++_workingThreads; }
task = _tasks.front();
_tasks.pop();
gotTask = true;
}
}
if( gotTask )
{
if( fs::is_directory( task ) )
{
for( fs::directory_iterator dirIter( task ), endIter; dirIter != endIter; ++dirIter )
{
if( fs::is_directory( dirIter->path() ) )
{
{ lock_guard<mutex> tl( _taskMutex );
_tasks.push( dirIter->path() ); }
_wakeCondition.notify_one();
}
else
{
for( auto& e : _args.extensions() )
{
if( !dirIter->path().extension().compare( e ) )
{
{ lock_guard<mutex> tl( _taskMutex );
_tasks.push( dirIter->path() ); }
_wakeCondition.notify_one();
//SearchFile( dirIter->path() );
}
}
}
}
}
else
{
for( auto& e : _args.extensions() )
{
if( !task.extension().compare( e ) )
{
if( _args.is_verbose() )
SearchFile( task );
else
SearchFileVerbose( task );
}
}
}
{ lock_guard<mutex> tc( _threadCountMutex) ;
--_workingThreads; }
}
}
}
}
void ThreadPool::SearchFileVerbose( string path )
{
fstream file;
file.open( path );
if( !file )
{
// error handling
}
else
{
{
lock_guard<mutex> cm( _consoleMutex );
cout << "nGrepping: " << path << endl;
int lineNumber = 1;
string line;
vector<GrepMatch> matches;
while( getline( file, line ) )
{
int lineMatches = 0;
sregex_token_iterator end;
for (sregex_token_iterator i(line.cbegin(), line.cend(), _args.regular_expression() );
i != end;
++i)
{
++lineMatches;
}
if( lineMatches > 0 )
{
GrepMatch match = GrepMatch( lineNumber, lineMatches, line );
matches.push_back( match );
cout << "Matched " << lineMatches << ": " << path << " [" << lineNumber << "] " << line << endl;
}
++lineNumber;
}
if( !matches.empty() )
{
_grepMatches[ path ] = matches;
}
}
}
}
我在互斥锁和condition_variable上都收到错误,说它们无法访问类内声明的私有成员。我的理解是,这是指复制构造函数?虽然我不明白为什么会发挥作用,因为我看不出我在哪里尝试复制,因为他们只是班级的私人成员。
根据最初的评论,我只实例化了 ThreadPool 的一个实例,它不会复制到任何地方。我唯一一次尝试接触互斥体是在我类的.cpp实现中。
谁能帮助我更好地了解为什么会发生这种情况?
对于那些感兴趣的人,这里是编译器输出:
1>------ Build started: Project: ultra_grep2, Configuration: Debug Win32 ------
1> ultra_grep_main.cpp
1> Unknown compiler version - please run the configure tests and report the results
1>c:usersjessedocumentsschoolsummer semester 2012concurrent processingproject 2ultra_grep v2ultra_grepthreadpool.hpp(39): error C2248: 'std::mutex::mutex' : cannot access private member declared in class 'std::mutex'
1> c:program files (x86)microsoft visual studio 11.0vcincludemutex(116) : see declaration of 'std::mutex::mutex'
1> c:program files (x86)microsoft visual studio 11.0vcincludemutex(107) : see declaration of 'std::mutex'
1> This diagnostic occurred in the compiler generated function 'ThreadPool::ThreadPool(const ThreadPool &)'
1> c:program files (x86)microsoft visual studio 11.0vcincludemutex(116) : see declaration of 'std::mutex::mutex'
1> c:program files (x86)microsoft visual studio 11.0vcincludemutex(107) : see declaration of 'std::mutex'
1> c:program files (x86)microsoft visual studio 11.0vcincludemutex(116) : see declaration of 'std::mutex::mutex'
1> c:program files (x86)microsoft visual studio 11.0vcincludemutex(107) : see declaration of 'std::mutex'
1> c:program files (x86)microsoft visual studio 11.0vcincludemutex(116) : see declaration of 'std::mutex::mutex'
1> c:program files (x86)microsoft visual studio 11.0vcincludemutex(107) : see declaration of 'std::mutex'
1>c:usersjessedocumentsschoolsummer semester 2012concurrent processingproject 2ultra_grep v2ultra_grepthreadpool.hpp(39): error C2248: 'std::condition_variable::condition_variable' : cannot access private member declared in class 'std::condition_variable'
1> c:program files (x86)microsoft visual studio 11.0vcincludecondition_variable(45) : see declaration of 'std::condition_variable::condition_variable'
1> c:program files (x86)microsoft visual studio 11.0vcincludecondition_variable(30) : see declaration of 'std::condition_variable'
1> This diagnostic occurred in the compiler generated function 'ThreadPool::ThreadPool(const ThreadPool &)'
1> ThreadPool.cpp
1> Generating Code...
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
问题是你的想法;编译器生成的复制构造函数和赋值运算符失败,因为互斥体和condition_variable不可复制。在许多情况下,编译器仍会为两者生成不容易看到的代码,即使您没有有意调用它们也是如此。根据我的经验,此错误通常是由于尝试将类型与标准库容器一起使用引起的。
您可能应该添加一个空的私有复制构造函数和赋值运算符,即使您没有这个问题;我认为尝试复制线程池是不可取的。
错误在以下位置:
1> ultra_grep_main.cpp
其中使用 ThreadPool
的复制构造函数:
此诊断发生在编译器生成的函数"ThreadPool::ThreadPool(const ThreadPool &)"中
我实际上很惊讶编译器没有指出复制构造函数隐式生成的源文件中的哪一行。
在注释中,您询问复制构造函数的外观。一个更好的问题是复制ThreadPool
对象是否有意义,答案是通常没有意义。为了改进错误消息,您可以将复制构造函数标记为deleted
,这样(希望)编译器将生成更好的错误报告,说明需要副本的位置:
class ThreadPool {
ThreadPool( ThreadPool const & ) = delete;
// ...
};
如果编译器不支持此 C++11 功能,则替代方法是声明复制构造函数,但不定义它。这将在使用复制构造函数的位置触发访问错误。
- 这是关于成员访问规则的正确摘要吗
- 为什么我在空指针错误(链表)中获取成员访问权限
- 成员访问是否在空指针上定义C++?
- C++ IDE 不会推断/自动完成对模板类中的 std::array 下标表达式的成员访问
- 为什么类成员数据必须是静态的才能被模板化类的模板化结构成员访问
- 为什么c++允许成员函数定义中实例的私有成员访问
- C/C++ 包含点的宏参数(成员访问运算符)
- 访问说明符(私有/公共/受保护)如何在内部工作(限制成员访问)?
- 如何将超类的受保护成员访问到其派生类. 如果已在派生类中声明了具有相同名称的函数?
- 内部类私有成员访问和封闭的友好性
- 通过 C++ 中的另一个结构成员访问结构
- 具体化 PRVALUES 成员访问的 decltype 行为不正确
- 常量表达式中的静态成员访问
- XVALUE来自类成员访问表达式
- 未经授权的私有类成员访问会产生编译时错误而不是运行时错误?
- 在 c++ 中,为什么 -> 被称为二进制中缀指针成员访问运算符?
- 如何访问模板参数的成员?“成员访问不完整的类型”
- 不明确的可变参数类成员访问
- C 受保护的成员访问
- 将typeID转换为静态成员访问(C )的命名空间