我的目标是将std::thread
对象保留为数据成员,并在需要时对其进行初始化
我无法执行此操作(如下面的代码中所示),因为std::thread
类的复制构造函数已被删除。还有其他办法吗?
class MyClass
{
public:
MyClass():DiskJobThread(){};
~MyClass();
void DoDiskJobThread();
private:
int CopyThread(const std::wstring & Source, const std::wstring & Target);
int MoveThread(const std::wstring & Source, const std::wstring & Target);
std::thread DiskJobThread;
};
MyClass::~MyClass()
{
DiskJobThread.join();
}
void MyClass::DoDiskJobThread()
{
std::wstring Source = GetSource();
std::wstring Target = GetTarget();
int m_OperationType = GetOperationType();
if (m_OperationType == OPERATION_COPY)
{
DiskJobThread = std::thread(&MyClass::CopyThread, *this, Source, Target);
}
else if (m_OperationType == OPERATION_MOVE)
{
DiskJobThread = std::thread(&MyClass::MoveThread, *this, Source, Target);
}
}
答案 0 :(得分:11)
如何将它包装在指针中?
std::unique_ptr<std::thread> thread_ptr;
// Look into std::make_unique if possible
thread_ptr = std::unique_ptr<std::thread>(new std::thread(...));
编辑:是的,其他人已经提到了它,我觉得不需要在这里添加它,但为了避免更多的downvote打桩,我会说:你是传递*this
而不是this
,从而复制您班级的实例。 (问题出现是因为它是不可复制的。通过this
你应该好好去。)
答案 1 :(得分:7)
创建后,您无法初始化线程对象;根据定义,在创建对象时进行初始化。但您可以使用swap
将线程对象移动到另一个:
std::thread thr1; // no thread of execution
std::thread thr2(my_function_object); // creates thread of execution
thr1.swap(thr2); // thr1 is now running the thread created as thr2
// and thr2 has no thread of execution
答案 2 :(得分:4)
您的问题是另一回事 - 您将MyClass
的实例传递给线程,而不是指向成员函数所期望的MyClass
的指针。只需像这样更改DoDiskJobThread()
(不要取消引用this
):
void MyClass::DoDiskJobThread()
{
std::wstring Source = GetSource();
std::wstring Target = GetTarget();
int m_OperationType = GetOperationType();
if (m_OperationType == OPERATION_COPY)
{
DiskJobThread = std::thread(&MyClass::CopyThread, this, Source, Target);
}
else if (m_OperationType == OPERATION_MOVE)
{
DiskJobThread = std::thread(&MyClass::MoveThread, this, Source, Target);
}
}
您收到错误是因为*this
导致尝试将MyClass
复制到线程函数中,并且删除了类的复制文件(因为删除了std::thread
的复制文件) 。但是,成员函数CopyThread
和MoveThread
无论如何都需要指针作为第一个(隐藏)参数。
<强> Live demonstration 强>
答案 3 :(得分:1)
我的目标是将
std::thread
对象保留为数据成员,并在需要时对其进行初始化。
由于默认构造的std::thread
对象没有关联的执行线程,因此可以通过将此类对象用作(移动)赋值操作的目标来实现此目的。但是,请注意,以下不是初始化,而是赋值:
std::thread th; // no thread of execution associated with th object
// ...
th = std::thread(func);
使用std::thread
创建的临时std::thread(func)
对象具有关联的执行线程。该执行线程的所有权通过移动分配转移到th
–即th
从临时名窃取该执行线程的所有权。
请注意,如果th
在分配时具有关联的执行线程,则std::terminate()
将被调用。