首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将非原子操作转换为原子操作?

如何将非原子操作转换为原子操作?
EN

Stack Overflow用户
提问于 2011-07-10 07:24:03
回答 5查看 14.2K关注 0票数 5

我试图理解原子的和非原子的operations.With与操作系统的关系,以及C.,根据维基百科的这里页面

考虑一个简单的计数器,不同的进程可以增加它。

非原子

天真的、非原子的实现:

读取存储器位置中的值;

在价值上增加一个;

将新值写入内存位置。

现在,假设两个进程正在运行增量单个共享内存位置:

第一进程读取存储器位置中的值;

第一个过程增加一个值;

但是,在将新值写回内存位置之前,它被挂起,第二个进程允许运行:

第二进程读取存储器位置中的值,与第一进程读取的值相同;

第二个过程增加了一个值;

第二个进程将新值写入内存位置。

如何才能使上述操作成为无表情操作。我对原子操作的理解是,任何不间断地执行的东西都是原子的。所以,例如

代码语言:javascript
复制
int b=1000;
  b+=1000;

按照我的理解,应该是一个原子操作,因为两个指令都不间断地执行,我是如何从某个人那里学到的,在C中没有什么叫做原子操作,所以上面的这两个语句都是非原子的。所以,我想要理解的是,在编程语言方面,什么是原子性与操作系统不同?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-07-10 07:32:44

代码语言:javascript
复制
int b = 1000;
b+=1000;

在指令级别转换为多个语句。至少,准备一个寄存器或内存,分配1000,然后获取该寄存器/内存的内容,将1000添加到内容,并将新的值(2000)重新分配到该寄存器。在没有锁定的情况下,操作系统可以在该操作的任何点挂起进程/线程。此外,在multiproc系统上,当您的操作正在进行时,不同的处理器可以访问该内存(在本例中不是寄存器)。

当您采取锁定(这是您将如何使这个原子),您是,在一定程度上,通知操作系统,它是不可以挂起这个进程/线程,这个内存不应该被其他进程访问。

现在,编译器可能会将上面的代码优化为简单的将2000赋值到b的内存位置,但为了这个答案,我忽略了这一点。

票数 3
EN

Stack Overflow用户

发布于 2011-07-10 10:02:30

C99没有任何方法使变量与其他线程相关的原子化。C99没有多个执行线程的概念。因此,您需要使用特定于编译器的扩展和/或CPU级指令来实现原子性。

下一个C标准,目前称为C1x,将包括原子操作。

即使如此,仅仅原子性只是保证一个操作是原子的,它并不保证当该操作对其他CPU可见时。为了实现可见性保证,在C99中,您需要研究CPU的内存模型,并可能使用一种特殊的CPU指令,称为栅栏或内存屏障。您还需要使用特定于编译器的编译器屏障将其告知编译器。C1x定义了几个内存顺序,当您使用原子操作时,您可以决定使用哪个内存顺序。

下面是一些例子:

代码语言:javascript
复制
/* NOT atomic */
b += 1000;

/* GCC-extension, only in newish GCCs 
 *   requirements on b's loads are CPU-specific
 */
__sync_add_and_fetch(&b, 1000);

/* GCC-extension + x86-assembly, 
 *   b should be aligned to its size (natural alignment), 
 *   or loads will not be atomic
 */
__asm__ __volatile__("lock add $1000, %0" : "+r"(b));


/* C1x */
#include <stdatomic.h>
atomic_int b = ATOMIC_INIT(1000);
int r = atomic_fetch_add(&b, 1000) + 1000;

所有这些看起来都很复杂,所以你通常应该坚持互斥,这会让事情变得更简单。

票数 4
EN

Stack Overflow用户

发布于 2011-07-10 07:33:31

b+=1000在我所知道的所有系统上编译成多个指令。因此,它不是原子的。

即使是b=1000也可以是非原子的,尽管您必须努力构建一个不属于原子的情况。

实际上,C没有线程的概念,所以在C中没有什么是原子的,您需要依赖编译器和工具的具体实现细节。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6639825

复制
相关文章

相似问题

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