为带有std::thread成员的类移动构造函数

MoveConstructor for classes with std::thread member

本文关键字:移动 构造函数 成员 thread std      更新时间:2023-10-16

我有点不确定写一个移动构造函数,对于一个正在执行成员函数的类,谁在成员线程中运行(复制构造函数/赋值被删除,作为一个很明显的原因)。到目前为止,我知道我复制了一个指向初始线程构造函数的对象指针,这样他就可以在正确的上下文中使用正确的函数。this->worker = std::thread (&class::working_loop,this);所以我假设我的问题是 std::线程移动构造函数改变函数上下文吗?

我对此表示怀疑,但我不确定线程移动构造函数有多复杂。

否则我假设,我必须停止线程在旧对象,移动/复制所有相关数据,并在新对象上创建一个新线程?

(对于下面的基本剥离示例)

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转换为类用户的vector

worker = std::thread (&Directory::working_loop,this);

移动时有危险

执行线程被绑定到对象的特定实例上的成员函数。如果对象在内存中改变了位置,那么所有的麻烦都在等待着你的线程。

不要只是移动它。

您没有显示线程的函数working_loop()的实现,我假设它只需要使用std::atomic<bool> stop来传达停止线程执行的条件。考虑将线程绑定为成员函数的替代实现(即自由函数或静态函数)。然后使用线程通信机制,如condition_variables,共享mutex对象甚至共享stop变量。