我正在尝试实现一个屏障函数,这样当一个线程调用waitBarrier()
时,它将等到所有其他n
线程调用该函数,之后所有线程都将继续,即排序同步构造。
我有以下代码:
int i = 0; // Shared variable. Initialized as 0 at the beginning.
waitBarrier() {
// CAS = Compare-and-swap, the first argument holds "old_val" the second the new
i = CAS(i, i+1);
// Spin until all n threads (number of all threads known prior) have been "here"
while (i != n) {}
}
如果n
个线程访问了这个,这个函数会起作用吗?原子函数的返回值的赋值是原子的吗?或者是否会出现竞争条件?
答案 0 :(得分:2)
首先,您必须指定寄存器的地址,您要比较和交换的值。这可以通过以下任一方式完成:
CAS(int* reg, int oldValue, int newValue)
或
reg.CAS(int oldValue, int newValue)
假设您的行现在是:
i = i.CAS(i, i+1)
想象一下两个线程同时调用waitBarrier()
。
假设正在以非原子方式评估原子函数的参数,即两个线程实际上都会调用i.CAS(0,1)
首先执行原子调用的人将成功将共享变量i设置为1。
由于CAS总是返回旧值,因此通过赋值i = OLD_VALUE_OF_i
,您实际上将共享变量重置为0。
不仅如此,而且想象你会完全省略该分配而只是进行CAS调用,无论线程执行CAS第二个,都会将共享值(现在为1)的值与i的初始值进行比较(在评估时为参数是0)哪个会失败,因此共享变量只会增加一次!
考虑到这两个方面,您的代码必须如下所示:
int i = 0;
waitBarrier() {
// Atomically increment the shared value i by 1
do {
int value = i;
} while (CAS(i, value, value + 1));
// Wait until all threads have passed the barrier
while (i != n) {}
}