block-quote On this pagechevron-down
copy Copy chevron-down
2012 C++ 新特性学习(八) — 原子操作和多线程库[多工内存模型] 这是我对C++新特性系统学习的最后一部分,之后就靠实践中再来看新标准的新特性啦。
Copy 在之前,我对这部分没太在意,直到看到了一篇文章 [http://blog.csdn.net/pongba/article/details/1659952](http://blog.csdn.net/pongba/article/details/1659952) 才意识到,C++的多线程操作也是个麻烦的问题。
简而言之,C++编译器在进行编译优化的时候,认为当前是单进程的,并且遵循**可观察行为**(Observable Behavior)不变的原则。就是说在可观察行为不变的情况下,操作是可以被改变顺序的,而单进程可观察行为不变,不代表在多进程的情况下仍然不变。还是上大牛的例子:
_**例子一:**_ 完全可以优化成
分别对于两个进程而言,可观察行为确实没有变化。而这种优化在某些时候确实会有比较明显的效果。但是很显然,语义变化了。在原来的结果里不可能发生 x和y都为0的情况,而优化过后,有可能出现。 再来个例子:
Copy for ( ... ) {
...
if ( mt )
pthread_mutex_lock ( ... );
x = ... x ...
if ( mt )
pthread_mutex_unlock ( ... );
}
// 当它被Register Promotion华丽丽地优化成
r = x ;
for ( ... ) {
...
if ( mt ) {
x = r ;
pthread_mutex_lock ( ... );
r = x ;
}
r = ... r ...
if ( mt ) {
x = r ;
pthread_mutex_unlock ( ... );
r = x ;
}
}
x = r ; 做何感想?所以说,现在的多线程库多少都是有缺陷的,要解决这一问题,只能从语言内存模型上动手脚了。
这里主要介绍两个库,原子操作和线程库 原子操作(Atomic) 头文件 #include 原子操作只支持C++类型 基本类型 std::atomic 扩展实现 std::atomic_char, std::atomic_int, std::atomic_uint 等是stl中的默认实现。 这个类型用于对数据进行原子操作,在操作的过程中可以指定内存规则。 主要的函数如下:
刚才提到了在原子操作时候的内存操作规则,内存操作规则主要是 std::memory_order,这是个枚举类型,里面包含着N多规则
在前面的原子操作的函数中,默认规则都是std::memory_order_seq_cst 此外,atomic还有一些标记类型和测试操作,比较类似操作系统里的原子操作
atomic_flag_test_and_set : 尝试设置为占用(原子操作)
atomic_flag_clear : 释放(原子操作)
前面的代码里已经用到了一点多线程库的东西了 包含文件: #include 涉及的类是 std::thread 构造函数里有两种
一种是传入函数指针和参数(VC里参数最多四个)。线程立即执行
另外需要注意 的是std::thread的等于操作符是必须要通过move语义的,并且如果joinable的话会执行std::terminate()。 函数茫茫多,建议用的时候看文档去,我这里就不废话了,上面已经用到一点了(PS:配std::bind是相当的华丽哦) 文档如这行 http://en.cppreference.com/w/cpp/threadarrow-up-right 以前写过一些测试代码,后来扔掉了。反正也很简单…
路漫漫其修远兮,吾将写代码而求索.
附上对C++11一些特性研究的总结: