看到《C++0x漫谈》系列之:多线程内存模型以前,哪里会想到一个多线程能够搞得这么复杂,各类例子看过以后感受三观尽毁……程序员没错,都是编译器优化惹的祸。固然,编译器也是合乎以前的标准,问题在哪里?规定多线程安全的标准相对缺失。那具体来说到底缺失的标准具体是什么呢?上面的文章最后只讲了“顺序一致性”,并无给出详细的技术上的答案。并且,我仍是有一个疑惑,若是上文中所说的pthread库等都没法保证多线程程序的正确性,那么多人用没出问题?没人反应?那Windows/Linux上的C++多线程程序都是怎么写的?html
接着,又看到了《程序员的自我修养》中关于加锁不能保证线程安全的一个错误这篇文章。从文章和下面跟帖留言的讨论能够看出:pthread库是有本身的一套内存可见性的规范,因此保证了程序的正常执行。而若是使用的锁机制没有保证这一点,就可能存在所说的加锁也不能保证线程安全的问题。但刘未鹏文中那个pthread的例子应该也不是假的,这是咱造纸太浅,没看懂~java
到了C++11具体的内存模型,参见C++11 并发指南七(C++11 内存模型一:介绍)c++
咱们必须对编译器和 CPU 做出必定的约束才能合理正确地优化你的程序,那么这个约束是什么呢?答曰:内存模型。C++程序员要想写出高性能的多线程程序必须理解内存模型,编译器会给你的程序作优化(静态),CPU为了提高性能也有乱序执行(动态),总之,程序在最终执行时并不会按照你以前的原始代码顺序来执行,所以内存模型是程序员、编译器,CPU 之间的契约,遵照契约后你们就各自作优化,从而尽量提升程序的性能。C++11 中规定了 6 种访存次序(Memory Order)程序员
可是具体的六种Memory Order怎样使用,区别感受仍是没讲清楚,关键是没有例子,等着看到了好的文章再补充~算法
———————————————看了多篇相关文章以后的分割线——————————————————— 感受这玩意儿真不是普通程序猿玩的啊~ 参考以下: c++11 内存模型解读——简单清楚。其中最后一段的几句话摘录以下:shell
内存模型方面的知识是很难理解,更难以正确使用的,在大多数状况下使用它而获得的些少性能优点,已经彻底不值得为此而带来的代码复杂性及可读性方面的损失,若是你还在犹豫是否要用这些相对底层的东西的时候,就不要用它,犹豫就说明还有其它选择,不到没得选择,都不要亲自实现 lock free 相关的东西。编程
漫谈C++11多线程内存模型——文中讲了“happens-before”概念,但看了图和例子仍是没看懂~哎,仍是智商不够啊~ 浅析C++多线程内存模型——文章很好,讲的较为详细了。并且他的博客上并行编程系列文章都很好值得一读。 C++11并发内存模型学习——文章中讲了consume,并且介绍了memory_order的几种类型。安全
看了陈皓的相关博客无锁队列的实现以后,感受使用CAS啥的高大上。可是看代码心中难免有些疑惑——自旋操做都是while循环——这是在空耗CPU啊,能高效么?这前几天看到C++11已经支持,因此本身写了个程序看看到底有多高效。因而用Xcode写了个demo对比atomic_flag和mutex对比测试。100个线程,每一个线程循环累加全局变量10000次。使用了自旋锁执行时间比使用mutex多不少,CPU使用率很是高,而mutex的CPU基本使用率很低。而Pthreads并行编程之spin lock与mutex性能对比分析这篇文章,测试并解释了上述现象,提出了自旋锁和mutex的使用场景:多线程
pthread_spin_lock应该与kernel里面的spin lock同样,锁定的关键区域要比较小才能够。 若是一个线程1得到spin后,另外一个线程2在另外一个CPU busy-wait该spin lock过程, 若是线程2在跑完这次CPU时间后,仍未得到该spin lock,刚说明,线程1锁的时间太长了。 应该使用mutex,而不该该使用spin lock.并发
活锁的概念 阿姆达尔法则(Amdahl’s Law):整体执行时间T = S + P/N 读写锁的解释 一个加锁操做通常须要100个CPU时钟周期 Doug Lea提到java.util.concurrent库中一个Non Blocking的算法的实现大概须要1我的年,总共约500行代码。
多线程程序中操做的原子性 ——汇编仍是很重要的,尤为是底层相关性较大的领域;此文还介绍了memory location的概念。