C++ 尝试将已删除的函数与C++;11线
我正在尝试创建一个ThreadPool类,它有这样一个构造函数C++ 尝试将已删除的函数与C++;11线,c++,multithreading,c++11,c++14,C++,Multithreading,C++11,C++14,我正在尝试创建一个ThreadPool类,它有这样一个构造函数 ThreadPool(大小\u t线程数) :workerThreads(线程数){ workerThreads.reserve(线程数); for(int i=0;i
ThreadPool(大小\u t线程数)
:workerThreads(线程数){
workerThreads.reserve(线程数);
for(int i=0;i
这无法为我编译,并引发以下错误
error: attempt to use a deleted function
__invoke(_VSTD::move(_VSTD::get<1>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:352:5: note: in instantiation of function template specialization
'std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void
(ThreadPool::*)(std::__1::function<void (char *, std::__1::list<std::__1::basic_string<char>,
std::__1::allocator<std::__1::basic_string<char> > > *)>), ThreadPool *, 2>' requested here
__thread_execute(*__p, _Index());
这也是同样的问题。我正在macos上用clang
c++14
编译代码
这是一个完整的程序,它可以复制
类线程池{
公众:
线程池(大小\u t线程数)
:workerThreads(线程数){
for(int i=0;i
由于您的doJob
成员函数具有类型为std::function
的参数job
,因此在调用此函数时需要提供相应的参数。因此,以这种方式在新线程中调用此函数是无效的:
std::thread(&ThreadPool::doJob, this) // no argument for job passed
您需要提供一个参数,或者,由于作业可能会从jobQueue
中退出队列,请从doJob
中删除job
参数:
void doJob()
{
... // dequeue job from jobQueue and execute it
你用什么样的容器?如果它是一个向量,则假定基础类型(恰好是std::thread)需要是可复制的,这恰好是不允许复制的。是的,它是一个
std::vector
您可以使用指针向量,因为std::thread指针是允许复制的。但这将取决于你加入或分离vector Destroyment上的所有线程。顺便说一句,在你的构造函数中,你正在创建numberOfThreads*2
个线程。此外,您的“保留”没有意义,因为您已经实例化了相同大小的向量。它不会为您分配更多内存。向后放置将为向量添加两倍的元素。假设您使用一个可复制的可构造类,您需要使用ThreadPool(size\t size):workerThreads(size,std::thread(&ThreadPool::doJob,this)){}
我在macOS装备上经常使用std::vector
,并且已经使用多年了。除了没有a的时间之外,我看到的唯一奇怪的事情是成员初始化列表中的workerThreads(size)
,这显然是错误的。没有workerThreads(size,std::thread(&ThreadPool::doJob,this))
,这将要求std::thread
是可复制的,我们已经知道它不是(也不是可复制分配的)。然而,它应该是可移动的proc()
是我的工作队列线程进程的样子。我的队列通常都是一个std::queue
,我通过一个旧但好的std::bind
模板生成一个push成员,该成员使用可变参数来创建一个call对象,如果有的话,再次使用转发的fn
可调用和转发的可变参数。这就是队列中的内容,并最终在线程池中被拉入和激发。注意到doJob
args很好。道具。