1.3 C++中的并行和多线程

来源:互联网 发布:南京行知基地住宿条件 编辑:程序博客网 时间:2024/06/14 05:37

对于多线程并行的标准化支持对于C++来说是一个新东西。只有在C++11中你才可以写不依赖于系统扩展库的多线程程序。为了弄清新C++线程库,了解他的历史是很重要的。

 1.3.1 C++多线程的历史

1998年C++标准没有意识到线程的存在,这导致许多的程序按照顺序的结构被编写。不仅仅如此,内存模型也没有标准定义,所以你离开指定编译器不能用1998C++写多线程程序.

当然,编译器厂商可以免费对语言添加扩展,而且多线程C API的流行-比如POSIX C标准和Microsoft Windows API-已经引领C++编译器厂商支持多线程的扩展,编译器支持通常只限于允许使用此平台的C API让C++运行库工作在多线程下。尽管很少有编译器提供正式的多线程内存模型,编译器和处理器已经可以很好的支持多线程的C++程序了。

不满足使用特定平台的C API 处理多线程。 C++ 程序员已经依赖他们的类库提供了面向对象的多线程支持,例如MFC程序框架和多用途的C++库,例如Boost和ACE已经封装了底层的API,提供更高级的简化任务的多线程工具。虽然类库多种多样,尤其是在启动新线程的时候,类的结构有很多相似。C++类库一个非常重要并且有利于程序员的设计,RAII(资源分配初始化)锁的使用确保当离开范围的时候互斥锁是打开的。

大多数情况下,编译器联合特定平台的API和跨平台的类库比如Boost和ACE为使用C++写多线程程序提供的坚实基础,但是标准的缺乏意味着缺乏线程感知的内存模型会引起问题,特别是对于想使用处理器提高程序性能或者编译器在各种平台间的跨平台性。

1.3.2 新标准的同步支持

所有的改变都是随着C++11的发布,不仅有了一个崭新的线程感知的内存模型,而且C++标准库已经包含了管理线程的类,带保护的共享数据,线程间同步,和底层原子操作。

新的C++线程库很大程度上是基于前面的C++类库。特别是,Boost线程库成为新类库最初的模型,许多类的名字和结构是Boost的升级版。由于新标准已经形成,这是一个双向的流动。boost类库在很多方面做了他自己的改变去适应新的C++标准,所以从Boost过度的用户应该发现很多相似的地方。

同步支持知识新标准的一个,语言上有许多加强的地方使程序员感觉写起来更容易。尽管这已经超出了本初的范畴,但是这些改变已经直接影响了线程库和它被使用的方式。附录A提供了一个对这些语言特性简洁的介绍。

原子操作的支持使程序员可以不使用平台指定扩展语言写出更加有效的程序,这是一个真正的高效可移植代码,编译器不仅要考平台,还要考虑优化操作,使程序最佳化

1.3.3 C++线程库的效率

对于C++开发者一般比较关心高效的计算能力,和C++类的底层应用,比如新C++标准线程库的效率,如果你在追求极大的效率,与直接使用底层应用相比,在使用高级应用的时候了解实现是非常重要的,这个开销就是抽象成本。

C++标准委员会在设计新的C++标准尤其是C++线程库的时候非常关注效率;设计目标之一是在提供相同的功能时与直接使用底层API相比较少的或者不增加开销,这个库已经被高效的用在了几个主要的平台上。

另一个目标是确保提供充足的底层应用,最后,新建一个支持直接控制bit和字节和线程同步的原子操作库的内存模型。这些原子类型和统一的操作现在可以被用在很多地方。选择新的标准将是代码维护起来更加容易和方便。

C++标准库也提供高层的抽象和工具是多线程代码更容易和错误更少。有时这些附加代码的使用会带来额外的开销因为需要执行他们,但是这些性能开销不一定意味着更高的损耗;一般这个开销不会高于你自己写的相同功能的开销,而且编译器也会提供一些内联优化。

有时候,高级的应用组件提供的额外功能超出了特定的使用范围,大多数情况下这不是问题:你不用为你不使用的功能支付开销。极少数情况下这些不使用的功能会影响其他代码的性能。如果你非常关注性能并且开销太大,你最好使用底层组件手动设计所需的功能。绝大多数情况下,增加的复杂度和出错几率远大于小小的性能提升带来的好处。尽管分析出瓶颈在于C++标准库,它可能是一个槽糕的应用程序设计。例如,如果太多的线程争夺同一个互斥锁,它将大大的影响性能。不要试图减少互斥锁操作的时间,而是应该重构应用程序以减少互斥锁的竞争操作,在第八章我们将设计减少互斥锁。

在极少数情况下C++没有提供必须的性能或者操作组件,这种情况下就必须使用特定的平台组件了。

1.3.4 特定平台组件

虽然C++标准库提供了综合的多线程和同步组件,但是任何平台提供的组件都超过了C++提供的。为了更容易的访问这些组件而又不放弃使用C++标准库带来的好处,在c++线程库类型中提供了一个native_handle的成员函数允许直接使用特定平台的API实现操作。本质上这个函数的操作已经超出了本书讨论的范畴。

当然,在使用特定平台的组件之前,了解标准库提供的组件是最重要的,让我们从一个例子开始吧。


0 1
原创粉丝点击