并发编程 CAS 原子操作简单总结

这里用 windows 的 Interlocked系列函数来举例

一直很迷惑Interlocked系列的原子操作函数到底有那些特性,之前只以为原子操 就是保证一个操作的完整性

比如一个i++ 分3步,先取原值 再+1 然后 存回去,cpu执行其中一步后可能就去执行其他指令了.

像是不是2个 Interlocked 对同一个变量的操作 是不是互斥(就是其中一个在执行,另一个需要等待),

Interlocked这句代码  跟它上文代码 的执行顺序是不是一定能保证,一直很迷惑。msdn上面的文档也看了几遍,一直不是很明白

后来才发现自己没看懂。


总结下相关知识点:

首先会导致并发编程的问题其中一些有:

1.多个线程同时操作一块内存

可能会出现一个线程写到一半,另一个读到了写了一半的值

2.一个操作会被分成多个指令执行 

比如 i++,这个会产生指令执行的空隙,

3.指令的乱序执行:编译器的代码优化,cpu的指令执行优化,会导致指令执行的乱序,

这种是否进行乱序优化的考虑只会针对当前线程的代码逻辑,当2部分操作 没有存在显性的关系,就可能被编译器或者cpu 优化成 乱序执行

比如 :

线程A

data = XXX  // 操作 1

flag = true // 操作 2

线程 B

if (flag)

{

data ...

}

编译器/cpu 可能对 操作1 ,操作2的执行顺序进行优化,操作2 可能被优先执行,这时候 线程B的 逻辑就出现问题


Interlocked 主要解决以上3个问题

Interlocked特性:

1.操作的整体性

比如i++操作,需要3步操作指令,Interlocked能保证这3步连续性,不被中断,要吗联系执行完,要吗不开始执行,不会出现执行第一步,被切换去执行其他指令, 请看翻译第4条

2.操作的互斥性:

对同一块内存操作是互斥,只能依次进行操作,一个Interlocked在操作当前变量,另一个线程的Interlocked就需要等待,请看翻译第5,6条

3.Interlocked 跟Interlocked上下文代码 执行顺序的保证

Interlocked带有内存屏障机制memory barrier,memory barrier用来保证内存操作的顺序,memory barrier的特性请看第7条

通过翻译了,理解了部分相关的文档说明,得出Interlocked以上特性:

(以下翻译加了一些自己的理解)

https://msdn.microsoft.com/en-us/library/windows/desktop/ms684122(v=vs.85).aspx

https://en.wikipedia.org/wiki/Memory_barrier

1.Simple reads and writes to properly-aligned 32-bit variables are atomic operations. In other words, you will not end up with only one portion of the variable updated; all bits are updated in an atomic fashion. ,

简单的读写(不使用interlocked函数)一个内存对齐32位的变量是能保证是原子操作,这里原子操作的意思是:这个32位的内存里面的值,不会出现只更新部分的时刻,也就是内存对齐32位变量的多个操作是依次进行的,然而内存不对齐就不能保证其原子性,因为可能需要2次读/写, 一个线程可能在读/写第一部分,另一个可能在读/写第二部分

ps:这里有个cpu总线读写机制,cpu一次只读/写固定带宽的内存,比如一次读128位,起始从0开始,在机制cpu只会按固定增量的起始位置去读/写,(n-1)*128 到 n*128 - 1,n从1开始。

所以要读/写从126 到 158内存块地址,就需要进行2次读/写操作, 把0-127 和 128-255都读/写过来,才能完成126-158内存块的读/写

2.However access is not guaranteed to be synchronized. If two threads are reading and writing from the same variable, you cannot determine if one thread will perform its read operation before the other performs its write operation.

然而,简单的读写访问不能保证是同步的,也就是不能保证A线程在读这个变量的时候,B线程一定写完 

3.Simple reads and writes to properly aligned 64-bit variables are atomic on 64-bit Windows. Reads and writes to 64-bit values are not guaranteed to be atomic on 32-bit Windows. Reads and writes to variables of other sizes are not guaranteed to be atomic on any platform.

简单的读写(不使用interlocked函数)一个内存对齐64位的变量在64位的windows系统上能保证是原子操作, 在32位系统上则不能保证, 其他大小的 读写操作在任何平台上都不能保证是原子的

4.The InterlockedIncrement and InterlockedDecrement functions combine the steps involved in incrementing or decrementing a variable into an atomic operation.

InterlockedIncrement and InterlockedDecrement, 把一个多步+操作或者一个-操作的 整合成一个 原子操作

5.This feature is useful in a multitasking operating system, in which the system can interrupt one thread's execution to grant a slice of processor time to another thread.

这个特性非常有用在多任务操作系统上, 在该系统上一个正在执行的线程能被打断,然后把处理器时间片让给其他线程,

6.Without such synchronization, two threads could read the same value, increment it by 1, and store the new value for a total increase of 1 instead of 2. The interlocked variable-access functions protect against this kind of error.

没有该原子操作的同步机制,2个线程都对一个变量做 +1 操作, 结果可能还是只加了1 而不是 2, 因为一个+1 操作分多步,先取原值,  再加+1,再存回去, 因为时机的关系 两个线程取值的时候可能都是 0, 各自加1以后 存回去还是1,实际上写程序的希望是加2。 interlocked能保证 +1操作的原子性,对同一个变量的内存 只能依次完成操作, 这样就达到 简单读写对齐的32位内存变量 能保证原子的情况,

7.A memory barrier, also known as a membar , memory fence or fence instruction, is a type of barrier instruction that causes a central processing unit(CPU) or compiler to enforce an ordering constraint on memory operations issued before and after the barrier instruction. This typically means that operations issued prior to the barrier are guaranteed to be performed before operations issued after the barrier.

https://en.wikipedia.org/wiki/Memory_barrier

内存屏障指令 能 让 cpu 或者编辑器 强制 约束 屏障指令前后的内存操作的顺序, 这就是说:屏障指令前的内存操作  一定能保证先执行完 相对于屏障指令后的内存操作

(换个说法就是:一定能保证  先执行完屏障指令前的内存操作,再执行屏障指令后的内存操作。  )

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • 接着上节 mutex,本节主要介绍atomic的内容,练习代码地址。本文参考http://www.cplusplu...
    jorion阅读 73,570评论 1 14
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,170评论 11 349
  • 一个简单的单例示例 单例模式可能是大家经常接触和使用的一个设计模式,你可能会这么写 publicclassUnsa...
    Martin说阅读 2,207评论 0 6
  • 我们一起来讨论讨论java内存模型。理解内存模型对多线程编程无疑是有好处的。 java代码是如何跑起来的 java...
    caixiangwang阅读 563评论 0 3
  • Java SE 基础: 封装、继承、多态 封装: 概念:就是把对象的属性和操作(或服务)结合为一个独立的整体,并尽...
    Jayden_Cao阅读 2,095评论 0 8