`
fp1203
  • 浏览: 3282 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
社区版块
存档分类
最新评论

原子操作与并发安全

阅读更多
一直以来,都对原子操作和并发安全都有些误解,认为一个操作不是原子的,那它就不是并发安全的,这样以来,就迟疑了,这么说来:
C语言一个简单的赋值语句也不是原子的咯? a = b是否是原子操作? 见代码如下:
int main() {
    int a = 0;
    int b = 2;
    a = b;
}


编译这段代码: g++ -c -g -Wa,-adlhn Assign.c > Assign.asm
可以发现(只显示a = b部分asm码):
movl	-8(%ebp), %eax
movl	%eax, -4(%ebp)

大家看,它由两条汇编指令完成操作,简单解释一下:
  • a ==> -4(%ebp)
  • b ==> -8(%ebp)
  • movl与mov参数顺序相反,movl SRC, DEST
  • movl -8(%ebp), %eax ==> movl b, %eax (先将寄存器%eax赋值为b的值)
  • movl %eax, -4(%ebp) ==> movl %eax, a (将a的值赋值为寄存器%eax的值)

经过这两个指令,最终实现了a = b的赋值

所以,似乎我可以负责任的说,a = b不是原子的。

好吧,既然它不是原子的,那它又是否是并发安全的呢?当然,上面这个例子似乎与并发没多大关系,那就定义这样一个类吧:
class CObject {
private:
    int _v;
public:
    CObject() { _v = 0; }
    void putValue(int v) { _v = v; }
    int  getValue() const { return _v; }
};

同样是只看_v = v部分的汇编指令
movl	8(%ebp), %eax
movl	12(%ebp), %edx
movl	%edx, (%eax)

解释如下:
  • 8(%ebp) ==> _v
  • 12(%ebp) ==> v
  • movl 8(%ebp), %eax ==> %eax赋值为_v的地址
  • movl 12(%ebp), %edx ==> %edx赋值为v的地址
  • movl %edx, (%eax) ==> %eax对应地址的值赋值为%edx对应的值

过程其实都一样,无非为了说明,赋值操作不是原子的。

如果是我以前的理解,不是原子操作就不是并发安全的,那并发程序该怎么写阿?

其实只能说,这是我的误解,首先我们要仔细想想,在什么情况下才会产生并发问题:
就我的理解,多个线程竞争共享数据时,才会有并发问题,回过头再来看上面那几行汇编代码,_v属于共享数据,可真正产生竞争只可能在movl %edx, (%eax),这个时候,可能有多个线程想进行这一步操作,事实上这个操作应该算是原子的吧,因此这样的赋值操作就应该是并发安全的。

分享到:
评论
2 楼 fp1203 2011-10-14  
jilen 写道
a,b是局部变量而已,这里有并发问题么?
还是我又二了?

前面main函数中的a,b只是为了解释原子性而已,讨论并发问题主要是针对后面的CObject的方法,你没有理解错
1 楼 jilen 2011-10-13  
a,b是局部变量而已,这里有并发问题么?
还是我又二了?

相关推荐

    C++中的原子操作:确保并发编程中的线程安全

    C++11标准引入了原子操作,作为保证并发程序中数据同步和线程安全的重要机制。本文将详细介绍C++中的原子操作,包括其基本概念、使用场景、API以及如何利用原子操作来避免竞态条件和死锁。 原子操作是C++并发编程中...

    并发编程——原子操作CAS.pdf

    文档中的示例代码展示了如何通过这些类来确保多线程环境下对共享变量的并发安全访问。例如,通过AtomicInteger类演示了如何安全地实现自增操作。 除了基本类型,文档还涉及到了数组类型原子更新类,例如...

    C++多线程原子操作

    但是,值得注意的是,虽然原子操作提高了并发安全性,但它们也会带来一定的性能开销,因为它们通常涉及到硬件级别的同步。因此,应该谨慎使用,只在真正需要确保并发安全的情况下才使用原子操作。 在实际开发中,...

    易语言线程安全之原子锁与读写锁

    线程安全通常通过同步机制来实现,其中包括原子操作和锁机制。本文将深入探讨易语言中的原子锁与读写锁。 原子操作是一种不可分割的操作,它在执行过程中不会被其他线程中断。在易语言中,原子操作常用于更新计数器...

    java多线程中的原子操作

    总结来说,Java多线程中的原子操作是保证并发安全的重要手段,通过使用`java.util.concurrent.atomic`包中的原子类,开发者可以编写出高效且线程安全的代码。同时,自定义的数据结构和工具类如CircularSet和...

    kotlinx.atomicfu,在kotlin中使用原子操作的惯用方法.zip

    5. **线程安全与并发策略**: 使用AtomicFu提供的原子类可以确保在多线程环境中的线程安全性,但开发者仍需要注意并发策略,比如避免死循环和活锁,合理设计同步逻辑,以及避免过度依赖原子操作导致的其他潜在问题。...

    java 并发操作之原子性与可视性1

    然而,由于`a++`本身不是原子操作,即使`a`是`volatile`的,仍然需要额外的同步措施来确保线程安全。 总结来说,原子性和可见性是Java并发编程中两个独立但又相互关联的概念。原子性关注的是操作是否不可分割,而...

    聊聊并发(5)原子操作的实现原理Java开发Java经验技

    在并发编程领域,原子操作是实现线程安全和高效代码的关键技术之一。本文将深入探讨Java开发中的原子操作实现原理,以及如何利用这些知识来优化Java应用。 首先,我们需要理解什么是原子操作。原子操作是指不可分割...

    3、并发编程之CAS&Atomic原子操作详解.pdf

    ### 并发编程之CAS与Atomic原子操作详解 #### 一、原子操作的概念与意义 在计算机科学领域,原子操作是指一系列的操作被视为一个整体,在执行过程中不会被其他进程或线程打断的操作。简而言之,它确保了一系列操作...

    原子操作、信号量、读写信号量和自旋锁的API

    这种特性使得原子操作成为保护共享资源免受并发访问的重要工具。 **应用场景**: 原子操作主要用于资源计数,例如引用计数。许多情况下,当一个对象被多个组件引用时,需要跟踪这个对象的引用数量,以确保在所有...

    Java 并发学习笔记:进程和线程,并发理论,并发关键字,Lock 体系,原子操作类,发容器 & 并发工具,线程池,并发实践

    原子操作类, 发容器 & 并发工具, 线程池, 并发实践 Java是一种面向对象的编程语言,由Sun Microsystems于1995年推出。它是一种跨平台的语言,意味着可以在不同的操作系统上运行。Java具有简单、可移植、高性能和...

    C++ 11 开发中的 Atomic 原子操作.rar_C++11、原子_atomic c++_c++ atomic使用_c++

    原子操作在并发环境下确保了数据的完整性,防止了数据竞争和其他并发问题。下面将详细介绍C++11中`std::atomic`的相关知识点。 1. **原子类型(Atomic Types)** C++11定义了一个`std::atomic`模板类,用于创建...

    Java 多线程与并发(8-26)-JUC原子类- CAS, Unsafe和原子类详解.pdf

    Java多线程与并发处理是Java编程中的高级话题,涉及到JUC(java.util.concurrent)包中的原子类、CAS(Compare-And-Swap)机制、Unsafe类以及多线程并发的无锁方案和线程安全的实现方法。 CAS是一种无锁的同步机制...

    一文读懂原子操作、内存屏障、锁(偏向锁、轻量级锁、重量级锁、自旋锁)、Disruptor、Go Context之上半部分.doc

    本文将从 CPU 硬件设计带来的优势和问题入手,讲解并发编程中的原子操作、锁机制、Disruptor 框架和 Go 语言中的 Context 概念。 一、并发编程概述 并发编程是指在多个任务之间分配执行时间的编程方式,以提高编程...

    并发编程过程中常用的原子锁和场景解答和模拟

    在并发编程中,原子操作和锁机制是保证多线程环境下数据一致性与程序正确性的关键工具。本主题将深入探讨这些概念以及它们在实际场景中的应用。 首先,我们需要理解什么是原子操作。原子操作是指在执行过程中不会被...

    并发编程线程安全样例代码.zip

    4. **原子变量类**:`Atomic*`系列类(如`AtomicInteger`, `AtomicBoolean`等)提供了一种无锁编程的方式,保证了操作的原子性。在示例中,我们可能会看到这些类如何被用来实现线程安全的数据更新。 5. **线程池**...

    锁与原子操作CAS以及无锁队列的底层实现相关资源

    在并发编程领域,锁和原子操作是实现线程安全的关键技术。CAS(Compare and Swap,比较并交换)是一种无锁编程的重要原语,而无锁队列则是利用这些原语构建高效并发数据结构的典范。下面我们将深入探讨这些概念及其...

    java并发编程与实践

    6. **原子操作与CAS**:Atomic类提供了一种无锁编程的方式,利用硬件级别的比较并交换(Compare and Swap, CAS)操作实现原子性更新,以提高并发性能。 7. **线程池设计**:线程池可以有效管理并发线程,避免频繁...

Global site tag (gtag.js) - Google Analytics