Implementing swap for class with std::mutex

前端 未结 2 1816
春和景丽
春和景丽 2021-02-07 17:10

Suppose we have a class with a std::mutex:

class Foo
{
    std::mutex mutex_;
    std::string str_;
    // other members etc
public:
           


        
相关标签:
2条回答
  • 2021-02-07 17:48

    You can use std::lock() to acquire the locks in a non-deadlocking way.

    If you want to use std::lock_guard, have them adopt the locks once taken:

    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_);
    

    If you prefer std::unique_lock, then construct them without locking, then call std::lock() to lock them both (this also works with 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_);
    

    In both cases, you should first test for lhs and rhs being the same object, because using std::lock with one mutex twice is undefined behavior:

    if (&lhs == &rhs)
        return;
    
    0 讨论(0)
  • 2021-02-07 18:08

    I don't think your swap implementation is safe. If another algorithm tries to lock rhs.mutex_ first and then lhs.mutex_, you may end up with a deadlock. Try std::lock() instead.

    0 讨论(0)
提交回复
热议问题