为什么 helgrind 抱怨这个程序?

Why helgrind complains on this program?

我有这样一个class:

class A
{
public:
    void swap(A& a)
    {
        lock(mutex_);
        vec_.swap(a.vec_);
    }

    void push(int elem)
    {
        lock(mutex_);
        vec_.push_back(elem);
    }

private:
    std::vector<int> vec_;
    Mutex mutex_; // doesn't matter what kind of mutex is
};

A a, b;

线程#1:

a.push_back(5);

线程#2:

b.swap(a);

它不是线程安全的吗? Valgrind 说可能存在数据竞争。我怀疑的是,在锁定 proc 切换到线程 #1 并修改 a,然后切换到 #2 并交换内容之前,首先调用了交换。但是应该没有问题,因为实际上指针被传递给交换,所以即使在从#1 线程交换修改之后也应该看到那个变化。这对 valgrind 来说很难看吗?

不,它不是线程安全的。问题是,尽管 A::swap 锁定了属于 this 的互斥量,但它没有锁定属于参数 a 的互斥量,因此一个线程可以修改 a 而另一个线程正在与 a 交换。您需要在 swap 中添加 lock 调用以锁定 a 的互斥锁。