假设我们想A使用一个类使线程安全std::mutex.我的复制构造函数和赋值运算符与下面的代码类似:
#include <mutex>
class A {
private:
int i;
mutable std::mutex mtx;
public:
A() : i(), mtx() { }
A(const A& other) : i(), mtx()
{
std::lock_guard<std::mutex> _lock(other.mtx);
i = other.i;
}
A& operator=(const A& other)
{
if (this!=&other) {
std::lock_guard<std::mutex> _mylock(mtx), _otherlock(other.mtx);
i = other.i;
}
return *this;
}
int get() const
{
std::lock_guard<std::mutex> _mylock(mtx);
return i;
}
};
Run Code Online (Sandbox Code Playgroud)
我不认为它有任何问题,除了在other复制之前被另一个线程销毁的可能性,我可以处理.
我的问题是我没有在任何地方看到这种模式,所以我不知道人们是否只是没有需要,或者由于我目前看不到的原因,这显然是错误的.
谢谢
注意:
这只是一个例子.我可以拥有任意类型的任意数量的成员变量,它不必只是一个int.
在Martin York对可能出现死锁的评论之后,这是一个使用复制和交换的更新版本(复制省略也是可能的,但它无法有效处理自我分配案例).
我也把int改为T,所以人们不能认为它是POD.
template<typename T>
class …Run Code Online (Sandbox Code Playgroud) 根据OpenMP内存模型,以下是不正确的:
int *p0 = NULL, *p1 = NULL;
#pragma omp parallel shared(p0,p1)
{
int x;
// THREAD 0 // THREAD 1
p0 = &x; p1 = &x;
*p1 ... *p0 ...
}
Run Code Online (Sandbox Code Playgroud)
我的例子如下所示:
int *p0 = NULL, *p1 = NULL;
#pragma omp parallel shared(p0,p1)
{
int x;
// THREAD 0 // THREAD 1
p0 = &x; p1 = &x;
#pragma omp flush
#pragma omp barrier
*p1 ... *p0 ...
#pragma omp barrier
}
Run Code Online (Sandbox Code Playgroud)
这会不正确吗?我在内存模型中找不到不允许这样做的东西.
我假设我的玩具示例是正确的,就像3.1中的内存模型一样,只要程序员确保它仍处于活动状态,它们就允许任务访问私有变量.鉴于任务可以解开,理论上它们可以在不同的工作线程内执行,因此允许OpenMP线程访问另一个的私有内存.