首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >分配原子函数的返回值

分配原子函数的返回值
EN

Stack Overflow用户
提问于 2014-02-05 19:01:20
回答 1查看 257关注 0票数 1

我正在尝试实现一个屏障函数,这样当线程调用waitBarrier()时,它将等待直到所有其他n线程都调用了该函数,之后所有线程都将继续进行,即一种同步构造。

我有以下代码:

代码语言:javascript
复制
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线程访问,这个函数能工作吗?原子函数的返回值的赋值是原子的吗?或者比赛条件会发生吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-08 16:08:10

首先,您必须指定寄存器的地址,它的值正在与其进行比较和交换。这可以通过以下任何一种方法来完成:

代码语言:javascript
复制
CAS(int* reg, int oldValue, int newValue)

代码语言:javascript
复制
reg.CAS(int oldValue, int newValue)

假设你现在的台词是:

代码语言:javascript
复制
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的计算时)进行比较,因此共享变量只会增加一次!

考虑到这两个方面,您的代码必须如下所示:

代码语言:javascript
复制
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) {}
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21586165

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档