c++ - 使用 std::mutex 实现类交换

标签 c++ multithreading c++11 mutex swap

假设我们有一个带有 std::mutexclass:

class Foo
{
    std::mutex mutex_;
    std::string str_;
    // other members etc
public:
    friend void swap(Foo& lhs, Foo& rhs) noexcept;
}

在这里实现 swap 方法的适当方法是什么?单独锁定每个互斥锁然后交换所有东西是否需要/安全?例如

void swap(Foo& lhs, Foo& rhs) noexcept
{
    using std::swap;
    std::lock_guard<std::mutex> lock_lhs {lhs.mutex_}, lock_rhs {rhs.mutex_};
    swap(ls.str_, rhs.str_);
    // swap everything else
}

我已经看到在 C++17 中,std::lock_guard 将具有 constructor采用多个互斥锁以避免死锁,但我不确定这是否是一个问题?

最佳答案

您可以使用 std::lock() 以非死锁的方式获取锁。

如果你想使用 std::lock_guard,让他们在获得锁后采用锁:

std::lock(lhs.mutex_, rhs.mutex_);
std::lock_guard<std::mutex> lock_a(lhs.mutex_, std::adopt_lock);
std::lock_guard<std::mutex> lock_b(rhs.mutex_, std::adopt_lock);
//swap actions
swap(ls.str_, rhs.str_);

如果您更喜欢 std::unique_lock,则在不加锁的情况下构造它们,然后调用 std::lock() 来锁定它们(这也适用于 std::lock_guard):

std::unique_lock<std::mutex> lock_a(lhs.mutex_, std::defer_lock);
std::unique_lock<std::mutex> lock_b(rhs.mutex_, std::defer_lock);
std::lock(lock_a, lock_b);
//swap actions
swap(ls.str_, rhs.str_);

在这两种情况下,您应该首先测试 lhsrhs 是否是同一个对象,因为将 std::lock 与一个互斥锁一起使用两次是未定义的行为:

if (&lhs == &rhs)
    return;

关于c++ - 使用 std::mutex 实现类交换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34853418/

相关文章:

c++ - 如何使用 find_if 获取最后一个迭代器?

c++ - 在 C++ 中定义离散概率分布

c++ - H264 编码 - 无法使用 VLC Player 播放视频

c++ - 是否有迭代 POSIX 环境变量的函数?

c - 在C中使用多线程做矩阵乘法

c# - C# 中线程的处理(死锁)

c - 下面的代码创建了多少线程,为什么?

c++ - 为什么从 std::string 的初始化列表中填充 std::vector 不调用 std::string 构造函数

c++ - 使用 extern const 将结构传递给模板。什么是外部?

c++ - 如何将方法作为参数传递?