首页 >后端开发 >C++ >如何使带有互斥体的 C 类可移动且线程安全?

如何使带有互斥体的 C 类可移动且线程安全?

Susan Sarandon
Susan Sarandon原创
2024-11-29 06:05:14609浏览

How Can I Make My C   Class with a Mutex Movable and Thread-Safe?

在 C 中处理可移动类型中的互斥体

问题:

由于非std::mutex 的可复制和不可移动性质,持有互斥体的类缺乏默认的移动构造函数,使得创建可移动的线程安全类型变得困难。

解决方案:

要为持有互斥体的 A 类实现线程安全的移动语义,采取以下策略:

移动构造函数:

A(A&& a) {
    WriteLock rhs_lk(a.mut_); // Lock the rhs mutex
    field1_ = std::move(a.field1_); // Move the data
    field2_ = std::move(a.field2_);
}

移动赋值运算符:

A& operator=(A&& a) {
    if (this != &a) {
        WriteLock lhs_lk(mut_, std::defer_lock);
        WriteLock rhs_lk(a.mut_, std::defer_lock);
        std::lock(lhs_lk, rhs_lk);
        field1_ = std::move(a.field1_);
        field2_ = std::move(a.field2_);
    }
    return *this;
}

复制构造函数:

A(const A& a) {
    ReadLock rhs_lk(a.mut_); // Lock the rhs mutex for reading
    field1_ = a.field1_; // Copy the data
    field2_ = a.field2_;
}

复制作业运算符:

A& operator=(const A& a) {
    if (this != &a) {
        WriteLock lhs_lk(mut_, std::defer_lock);
        ReadLock rhs_lk(a.mut_, std::defer_lock);
        std::lock(lhs_lk, rhs_lk);
        field1_ = a.field1_;
        field2_ = a.field2_;
    }
    return *this;
}

其他注意事项:

  • 为了方便起见,定义一个 ReadLock 和 WriteLock 类型别名。
  • 记住使用 std::lock 锁定两个互斥体以防止移动赋值运算符死锁。
  • 考虑在 C 14 中使用 std::shared_timed_mutex 以允许并发读取。
  • 使用适当的互斥锁保护访问 A 类内部状态的任何成员函数或自由函数。
  • 如有必要,添加数据成员锁来存储ReadLock和WriteLock对象,以避免在执行过程中默认构造成员正在复制。

以上是如何使带有互斥体的 C 类可移动且线程安全?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn