【问题标题】:Move semantics for class with mutex使用互斥锁移动类的语义
【发布时间】:2023-12-24 12:57:01
【问题描述】:

我有一个类处理程序:

class Handler {
private:
    std::mutex _mutex_list[4];
    std:list<Person*> _waiting_list[4];
    std::thread __runner_t;
public:
    virtual void start();
};

我正在尝试在新线程中启动处理程序:

Handler* handler = new Handler();
std::thread(&Handler::start, handler);

问题是显然 std::thread 需要类的传输构造函数,我无法将其定义为默认值,因为 std::mutex 无法复制。

我定义了一个自定义复制构造函数,它只复制列表但重新初始化互斥体数组和线程。

这里是:

Handler(const Handler& other) :
 _mutex_list(), _waiting_list(other._waiting_list), _runner_t() {};

当然不起作用,因为编译器要求传输构造函数。

我不知道如何实现同样的转移。

这是一个正确的解决方案吗?有没有更好的解决方案?

感谢您的帮助。

【问题讨论】:

  • 你能给我们一个minimal reproducible example吗? Handler* handler = new Handler(); std::thread(&amp;Handler::start, handler); 应该可以工作,因为你没有复制对象,只是一个指向它的指针。
  • 这并没有解决问题,但包含两个连续下划线 (__runner_t) 的名称和以下划线后跟大写字母的名称保留供实现使用。不要在你的代码中使用它们。
  • 这个问题的答案在这里:*.com/a/29988626/576911
  • 感谢所有回复,在尝试做最小、完整和可验证的示例时,它终于解决了。它有一个逻辑错误,我传递的是对象本身而不是指针(在另一个文件中声明和定义)。

标签: c++ multithreading mutex copy-constructor move-semantics


【解决方案1】:

没有transfer 构造函数,有移动构造函数。您的代码有一个逻辑问题 - 您正在创建一个线程并将您的对象复制到其中,但该对象拥有该线程,这是错误的。

我想说,如果你有一个拥有线程的对象,那么运行这个线程应该是它自己的函数,比如:

class Handler {
    ...
    void start() {
        __runner_t = std::thread(&thread_func, this);
    }
};

您遇到的技术编译错误虽然可以解决,但突出了逻辑问题。

【讨论】:

  • 感谢您的回复,正如我在上面的评论中所说,它已经修复了。 Handler 中的线程对象不是调用线程,而是另一个由 handler 按需启动的对象。
  • @SergeyA 你的Handler::start() 不需要在它创建的std::thread 上调用detach() 吗? std::thread(&amp;thread_func, this).detach()
  • @RemyLebeau 我的意思是将结果保存在__runner_t,让我编辑一下。没有这个是,它会立即中止。