为什么 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
的互斥锁。
我有这样一个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
的互斥锁。