我正在尝试实现一个屏障函数,这样当线程调用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线程访问,这个函数能工作吗?原子函数的返回值的赋值是原子的吗?或者比赛条件会发生吗?
发布于 2014-02-08 16:08:10
首先,您必须指定寄存器的地址,它的值正在与其进行比较和交换。这可以通过以下任何一种方法来完成:
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) {}
}https://stackoverflow.com/questions/21586165
复制相似问题