我对编写移动构造函数有点不确定,对于正在执行成员函数的类,它在成员线程中运行(复制构造函数/ assign已被删除,因为其中一个作为afaik明显的原因)。
到目前为止,我知道我正在复制一个指向初始线程构造函数的对象指针,因此他可以在正确的上下文中使用正确的函数。
this->worker = std::thread (&class::working_loop,this);
所以我假设我的问题是 std :: thread移动构造函数是否更改了函数上下文?
我对此表示怀疑,但我不确定线程移动构造函数有多复杂。
否则我假设,我必须停止旧对象中的线程,移动/复制所有相关数据,并在新对象上创建一个新线程?
(对于下面的基本剥离示例)
class Directory
{
private:
std::thread worker;
std::atomic<bool> stop;
void working_loop();
public:
void start_monitor();
void stop_monitor();
Directory (Directory &&dir);
Directory(const Directory&) = delete;
Directory& operator= (const Directory&) = delete;
~Directory();
};
void Directory::start_monitor()
{
stop = false;
worker = std::thread (&Directory::working_loop,this);
}
void Directory::stop_monitor()
{
stop = true;
if (worker.joinable())
{
worker.join();
}
else
{
std::cerr << "Warning thread " << worker.get_id() << " already joined!" << std::endl;
}
}
编辑:工作循环连接到数据库以获取属于该对象的更多数据(即目录),并将其用于以后的目录扫描/通知回调,而类用户使用它来组织多个目录。类类型应该能够被std :: vector :: emplace_back编辑成类用户的向量。
答案 0 :(得分:2)
worker = std::thread (&Directory::working_loop,this);
移动时会有危险...
执行线程绑定到on对象的特定实例上的成员函数。如果对象在内存中更改位置,则会出现各种麻烦。
不要只是移动它。
您没有显示线程函数working_loop()
的实现,我假设它只需要使用std::atomic<bool> stop
来传达条件以停止线程的执行。考虑将被绑定为成员函数的线程的实现的替代方案(即自由函数或静态函数)。然后使用线索通信机制,例如condition_variables
,共享mutex
个对象,甚至共享stop
变量。