【发布时间】:2020-06-09 15:58:46
【问题描述】:
我想自动交换定义为结构VValue 的两个大内存位置。由于结构的大小比long 大,因此没有架构支持直接比较和交换两个结构。但是,一种方法是交换两个结构的指针并间接交换内存位置。
下面是我应该将oldValue 与b 交换的代码。 compare 和 swap 内置函数在 do-while 循环中使用,以确保在交换发生时 oldValue 的值不会被其他线程更改(此代码 sn-p 是更复杂的与其他条件交换。为简洁起见,条件被删除)。
template<typename A, typename B, typename C, typename D>
struct VStructType{
A a;
B b;
C c;
D d;
VStructType () {
;
}
VStructType (A a, B b, C c, D d) {
this->a = a;
this->b = b;
this->c = c;
this->d = d;
}
};
typedef VStructType<uint32_t,uint32_t,uint32_t,uint32_t> VValue;
bool swap(VValue* oldValue, VValue b)
{
bool r = 0;
VValue* c;
VValue *w = new VValue();
do{
c = oldValue;
w->a = b.a;
w->b = b.b;
w->c = b.c;
w->d = b.d;
} while (!(r = __sync_bool_compare_and_swap(&oldValue, c, w)));
return r;
}
int main()
{
VValue oldValue = VValue(1,2,3,4);
VValue b = VValue(10,12,2,8);
swap(&oldValue, b);
}
问题是在swap函数内部swap之后,oldValue的值变成了新的值,但是从swap函数返回后oldValue没有改变。似乎对oldValue 的引用是一个临时引用,当交换发生时,它只交换新引用而不是指向oldValue 的实际指针。将引用传递给__sync_bool_compare_and_swap 函数的原因是第一个参数是指向要与之比较值的变量的指针。
我的问题:
1)有没有办法将oldValue的指针的指针直接传递给__sync_bool_compare_and_swap函数?
2) 当oldValue 是数组中的一个元素时,这种方法是否可行?
注意:使用g++ -latomic -std=gnu++11编译。
【问题讨论】:
-
老实说,我什至不知道这段代码发生了什么。什么与什么交换?什么是新值,什么是旧值,为什么代码中突然出现“新”?为什么只交换指针就不行?
-
我想将
oldValue与b交换,两者都只是结构实例。由于我需要同步我的代码,我必须使用原子原语。 -
@Branky: 好的,没那么糟糕,但你收到了
oldValue作为调用者指针的副本(它引用相同的数据,但没有链接给调用者,因为它不是参考)。所以换出它的值对调用者来说并不重要,调用者的 pointer 不能改变,只能改变它指向的东西(并且只要函数的指针副本没有被重新分配指向别处)。如果要更改调用者的指针,则需要接收对指针或双指针的引用。 -
@Branky:Pointers are not references。如果您不了解它们之间的区别,那么现在考虑在 C++ 中实现复杂的无锁算法还为时过早。你需要先走路才能跑步。照原样,您的代码无论如何都无法工作;你想在调用者中交换一个指针,但是调用者没有有一个指针,它给了你一个指向它的堆栈分配内存的指针。调用者中没有指向更改的指针。
-
你有一个
new,结果既不是由拥有类(如智能指针)管理,也不是与delete一起发布。您的函数中存在内存泄漏。
标签: c++ pass-by-reference compare-and-swap