我的目标是将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);
}
}
您的问题是其他问题-您正在将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
复制到线程函数中,并且类的复制ctor被删除(因为std::thread
的复制ctor被删除)。但是,成员函数CopyThread
和MoveThread
无论如何都需要一个指针作为第一个(隐藏的)参数。
如何将其包装在指针中?
std::unique_ptr<std::thread> thread_ptr;
// Look into std::make_unique if possible
thread_ptr = std::unique_ptr<std::thread>(new std::thread(...));
Edit:是的,其他人都提到了它,我不认为需要在此处添加它,但是为了避免更多的下降桩,我要说:您正在通过*this
而不是this
从而复制您的类的实例。 (出现问题是因为它不可复制。通过this
,您应该就可以了。)
创建线程对象后,您不能初始化;根据定义,初始化是在创建对象时发生的。但是您可以使用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
我的目标是保留
std::thread
对象作为数据成员,并在需要时对其进行初始化。
由于默认构造的std::thread
对象没有关联的执行线程,因此可以通过将此类对象用作(移动)赋值操作的目标来实现此目的。请注意,以下内容不是initialization,而是assignment:
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()
。