码迷,mamicode.com
首页 > 编程语言 > 详细

C++多线程模型与锁

时间:2014-11-04 13:22:39      阅读:214      评论:0      收藏:0      [点我收藏+]

标签:blog   http   ar   os   使用   for   sp   on   art   

C++内存模型

看到《C++0x漫谈》系列之:多线程内存模型之前,哪里会想到一个多线程可以搞得这么复杂,各种例子看过之后感觉三观尽毁……程序员没错,都是编译器优化惹的祸。当然,编译器也是合乎之前的标准,问题在哪里?规定多线程安全的标准相对缺失。那具体来讲到底缺失的标准具体是什么呢?上面的文章最后只讲了“顺序一致性”,并没有给出详细的技术上的答案。而且,我还是有一个疑惑,如果上文中所说的pthread库等都无法保证多线程程序的正确性,那么多人用没出问题?没人反应?那Windows/Linux上的C++多线程程序都是怎么写的?

接着,又看到了《程序员的自我修养》中关于加锁不能保证线程安全的一个错误这篇文章。从文章和下面跟帖留言的讨论可以看出:pthread库是有自己的一套内存可见性的规范,所以保证了程序的正常执行。而如果使用的锁机制没有保证这一点,就可能存在所说的加锁也不能保证线程安全的问题。

到了C++11具体的内存模型,参见C++11 并发指南七(C++11 内存模型一:介绍)

我们必须对编译器和 CPU 作出一定的约束才能合理正确地优化你的程序,那么这个约束是什么呢?答曰:内存模型。C++程序员要想写出高性能的多线程程序必须理解内存模型,编译器会给你的程序做优化(静态),CPU为了提升性能也有乱序执行(动态),总之,程序在最终执行时并不会按照你之前的原始代码顺序来执行,因此内存模型是程序员、编译器,CPU 之间的契约,遵守契约后大家就各自做优化,从而尽可能提高程序的性能。C++11 中规定了 6 种访存次序(Memory Order)

但是具体的六种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.

C++多线程模型与锁

标签:blog   http   ar   os   使用   for   sp   on   art   

原文地址:http://my.oschina.net/u/1864567/blog/340471

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!