`
saybody
  • 浏览: 908090 次
  • 性别: Icon_minigender_2
  • 来自: 西安
文章分类
社区版块
存档分类
最新评论

C++的可移植性和跨平台开发[6]:多线程

阅读更多

  最近一个多月写的帖子比较杂,导致本系列又好久没更新了。结果又有网友在评论中催我了,搞得我有点囧。今天赶紧把多线程篇补上。上次聊操作系统 的时候,由于和OS有关的话题比较琐碎,杂七杂八说了一大堆。当时一看篇幅有点长,就把多进程和多线程的部分给留到后面了。<!-- program-think-->

  ★编译器
  ◇关于C运行库选项
  先来说一个很基本的问题:关于C运行库(后面简称CRT:C Run-Time)的设置。本来不想聊这么低级的问题,但周围有好几个人都在这个地方吃过亏,所以还是讲一下。
  大部分C++编译器都会自带有CRT(可能还不止一个)。某些编译器自带的CRT可能会根据线程的支持分为单线程CRT和多线程CRT两类。当你要进行多线程开发的时候,别忘了确保相关的C++工程项目使用的是多线程的CRT。否则会死得很难看。
  尤其当你使用Visual C++创建工程项目,更加要小心。如果新建的工程项目是不含MFC的(包括Console工程和Win32工程),那工程的默认设置会是使用“单线程CRT”,如下图所示:

不见图、请
  ◇关于优化选项
  “优化选项”是另一个很关键的编译器相关话题。有些编译器提供号称很牛X的优化选项,但是某些优化选项可能会有潜在的风险。编译器可能自作主张打乱执行指令的顺序,从而导致出乎意料的线程竞态问题(Race Condition,详细解释看“这里 ”)。刘未鹏同学在“C++多线程内存模型 ”里举了几个典型的例子,大伙儿可以去瞧一瞧。
  建议只使用编译器常规的速度优化选项即可。其它那些花哨的优化选项,增加的效果未必明显,但是潜在的风险不小。实在不值得冒险。
  以GCC为例:建议用-O2 选项即可(其实-O2 是一堆选项的集合),没必要冒险用-O3 (除非你有很充足的理由)。除了-O2-O3 之外,GCC还有一大坨(估计有上百个)其它的优化选项。如果你企图用当中的某个选项,一定要先把它的特性、可能的副作用都摸清楚,否则将来死都不知道怎么死的。

  ★线程库的选择
  由于当前的C++ 03标准几乎没有涉及线程相关的内容(即使将来C++ 0x包含了线程的标准库,编译器厂商的支持在短期内也未必全面),所以在未来很长的一段时间,跨平台的多线程支持还是要依赖第三方库。所以线程库的选择是大大滴重要。下面大致介绍一下几个知名的跨平台线程库。
  ◇ACE
  先说一下ACE这个历史悠久的库。如果你之前从未接触过它,先看“这里 ”扫盲。从ACE的全称(Adaptive Communication Environment)来看,它应该是以“通讯”为主业。不过ACE对“多线程”这个副业的支持还是非常全面的,比如互斥锁(ACE_Mutex)、条件变量(ACE_Condition)、信号量(ACE_Semaphore)、栅栏(ACE_Barrier)、原子操作(ACE_Atomic_Op)等等。对某些类型比如ACE_Mutex还细分为线程读写锁(ACE_RW_Thread_Mutex)、线程递归锁(ACE_Recursive_Thread_Mutex)等等。
  除了支持很全面,ACE还有另一个很明显的优点,就是对各种操作系统平台及其自带的编译器支持很好。包括一些老式的编译器(比如VC6),它也能够支持(此处所说的支持 ,不光是能编译通过,而且要能稳定运行)。这个优点对于跨平台开发那是相当相当滴明显。
  那缺点捏?由于ACE开工的年头很早(大概是上世纪九十年代中期),那会儿很多C++的老特性都还没出来(更别提新特性了),所以感觉ACE整个的风格比较老气,远不如boost那么时髦前卫。
  ◇boost::thread
  boost::thread正好和ACE形成鲜明对照。这玩意貌似从boost 1.32版本开始引入,年头比ACE短。不过得益于boost里一帮大牛的支持,发展还是蛮快的。到目前的boost 1.38版本,也能够支持许多特性了(不过似乎没ACE多)。鉴于很多C++标准委员会的成员云集在boost社区中,随着时间的推 移,boost::thread终将成为C++线程的明日之星,前途无量啊!
  boost::thread的缺点就是支持的编译器不够多,尤其是一些老式 编译器(很多boost的子库都有此问题,多半因为用了一些高级的模板语法)。这对于跨平台而言一个比较明显的问题。
  ◇wxWidgetsQT
  wxWidgets和QT都是GUI界面库,但是它们也都内置和对线程的支持。wxWidgets线程的简介可以看“这里 ”,关于QT线程的简介可以看“这里 ”。这两个库对线程的支持差不多,都提供了诸如mutex、condition、semaphore等常用的机制。不过特性没有ACE丰富。
  ◇如何权衡
  对于开发GUI软件并已经用上了wxWidgets或者QT,那你可以直接用它们内置的线程库(前提是你只用到基本的线程功能)。由于它们内置的线程库,特性稍嫌单薄。万一你需要某高级的线程功能,那得考虑替换成boost::thread或ACE。
  至于boost::thread和ACE的取舍,主要得看软件的需求了。如果你要支持的平台挺多挺杂,那建议选用ACE,以免碰上编译器不支持的问题。如果你只需要支持少数几个主流的平台(比如Windows、Linux、Mac),那建议用boost::thread。毕竟主流操作系统上的编译器,对boost的支持还是蛮好的。

  ★编程上的注意事项
  其实多线程开发,需要注意的地方挺多的,我只能大致列几个印象比较深的注意事项。
  ◇关于volatile
  说到多线程编程可能碰到的陷阱,那就不得不提到volatile 关键字。如果你对它还不甚了解,先看“这里 ”扫盲一下。由于C++ 98和C++ 03标准都没有定义多线程的内存模型,而标准中也就volatile 和线程沾点儿边。结果导致C++社区中有相当多的口水都集中在volatile 身上(其中有不少C++大牛的口水)。有鉴于此,我这里就不再多啰嗦了。推荐几个大牛的文章:Andrei Alexandrescu 的文章“这里 ”、还有Hans Boehm的文章“这里 ”和“这里 ”。大伙儿自个儿去拜读一下。
  ◇关于原子操作
  有些同学光知道多个线程的竞争写 需要加锁,却不知道多个 单个 也需要保护。比如有某个整数int nCount = 0x01020304;在并发状态下,一个写线程去修改它的值nCount = 0x05060708;另一个读线程去获取该值。那么读线程有没有可能读取到一个“坏”的(比如0x05060304)数据捏?
  数据是否坏掉,取决于对nCount的读和写是否属于原子操作。而这就依赖于很多硬件相关的因素了(包括CPU的类型、CPU的字长、内存对齐的字节数等)。在某些情况下,确实可能出现数据坏掉。
  由于我们讨论的是跨平台的开发,天晓得将来你的代码会在啥样的硬件环境下执行。所以在处理类似问题的时候,还是要用第三方库提供的原子操作类/函数(比如ACE的Atomic_Op)来确保安全。
  ◇关于对象的析构
  在之前的系列帖子“C++对象是怎么死的? ”里面,已经分别介绍了Win32平台和Posix平台下线程的 自然死亡问题。由于上述几个跨平台的线程库底层还是要调用操作系统自带的线程API,所以大伙儿还是要尽最大努力确保所有 线程都能够自然死亡。

  今天的话题就聊到这里,下一次聊多进程的话题。


版权声明
本博客所有的原创文章,作者皆保留版权。转载必须包含本声明,保持本文完整,并以超链接形式注明作者编程随想 和本文原始地址:

http://program-think.blogspot.com/2009/04/cxx-cross-platform-develop-6-thread.html

分享到:
评论

相关推荐

    c++ 跨平台线程 线程池

    - 在C++中,这样的库可以帮助开发者编写无需关心底层操作系统差异的代码,提高代码的可移植性。 4. **testthreadpool.cpp**: - 这个文件很可能是线程池的测试程序,用于验证`threadpool.c`和`threadpool.h`的...

    c++跨平台开发

    总之,C++跨平台开发是一项复杂但值得投入的任务,它不仅可以扩大应用的受众范围,还可以提高代码的重用率和开发效率。通过采用上述策略和技术,开发者可以有效地克服跨平台开发中的挑战,创建出高质量、高可移植性...

    C++封装的一个跨平台的线程类和锁类

    在C++编程中,线程和锁是并发编程的核心元素,尤其在开发跨平台的应用程序时,需要确保代码能够在不同的操作系统环境下正常运行。本项目提供了一个C++封装的线程类和锁类,使得开发者可以方便地在Linux和Windows平台...

    C++ Qt6 跨平台开发(机翻).zip

    C++ Qt6 跨平台开发是一项重要的技术,它允许开发者使用C++语言构建可以在多个操作系统上运行的应用程序,包括Windows、Linux、macOS、Android以及iOS等。Qt库提供了丰富的功能,涵盖了图形用户界面(GUI)、网络...

    C++跨平台开发技术指南 中英文版 pdf

    这些是进行跨平台开发的基础,因为它们确保代码的可移植性和复用性。 接下来,作者深入讨论了跨平台开发的关键问题,如处理操作系统差异、文件系统接口、线程与并发、网络编程以及图形用户界面(GUI)构建。在不同...

    跨平台软件开发C&C++

    C和C++是两种广泛用于跨平台开发的语言,因为它们具有高度的灵活性和广泛的可移植性。以下是对这两个主题的详细阐述: 一、跨平台软件开发 跨平台软件开发是指编写一次代码,然后能够在多种操作系统(如Windows、...

    开源的win32平台c++多线程开发包

    综上所述,这个开源的win32平台C++多线程开发包提供了一个在Windows环境下编写多线程程序的解决方案,它基于C++语言和POSIX线程标准,通过`pthreadVC2.dll`和`pthreads`库实现了跨平台的线程功能。对于希望在Windows...

    C++多线程基类C++多线程基类C++多线程基类

    C++多线程是编程中一个重要的概念,它允许程序同时...这不仅提高了代码的可读性和可维护性,还简化了跨平台的移植工作。然而,编写多线程代码时仍需关注线程安全、资源管理和同步问题,以确保程序的正确性和高效性。

    C++11多线程

    在C++11之前,实现多线程通常需要依赖平台特定的API,而C++11标准库提供了跨平台的多线程支持,让开发者能够更容易地编写出高效且可移植的多线程程序。 一、线程基础 1. `std::thread` 类:这是C++11中用于创建和...

    LinuxWindows平台C++多线程及定时器毕业论文.docx

    该库可以满足不同平台上的多线程编程需求,提高了程序的可移植性和可靠性。 结论: 本论文设计和实现了一个统一的多线程库和定时器类库,abolished 了平台之间编程上的差异,提高了程序的可靠性和高效性。该论文的...

    跨平台的C++线程模板类和信号量及互斥量模板类

    在C++编程中,跨平台性是一个重要的考量因素,特别是在涉及到操作系统底层机制如线程、锁和信号量等时。本文将深入探讨标题和描述中提及的“跨平台的C++线程模板类”以及“信号量及互斥量模板类”。 首先,线程是...

    跨平台开发的一些资料合集

    从C++的基础到深入的MacOS和Android开发,再到实现软件可移植性的策略,每一个部分都对理解和掌握跨平台开发的核心概念至关重要。通过深入学习这些内容,开发者可以拓宽自己的视野,提高代码复用性,降低维护成本,...

    基于嵌入式Linux的具有可移植性的C++程序开发框架

    在IT行业中,嵌入式系统和物联网(IoT)领域的发展日新月异,而“基于嵌入式Linux的具有可移植性的C++程序开发框架”正是这些领域的重要工具之一。 Embedme,作为这样一个框架,旨在简化Linux应用程序的开发过程,...

    跨平台的C++程序开发框架

    标题和描述中提到的“跨平台的C++程序开发框架”通常是指能够在多种操作系统上运行的C++编程框架,如Windows、Linux、macOS等。这样的框架为开发者提供了统一的API,使得代码可以在不同的平台上无缝迁移,提高了软件...

    跨平台C++计时器类windows linux

    此外,为了使VTimer更具可移植性,可能还采用了条件编译或预处理器指令(如`#ifdef`和`#endif`),来处理Windows和Linux之间的API差异。这样,同一段代码可以在两种操作系统下正确编译和运行。 总的来说,这个跨...

    C++开源跨平台类库集

    它支持多种操作系统和编译器,并且具有高度的可移植性。STLport的目标是提供一个与C++标准尽可能接近的实现,同时也兼容不同的编译器版本。例如,在早期的VC7.1版本中,由于该编译器对C++标准的支持不够完善,因此...

    C++跨平台条件变量和互斥锁封装

    在C++编程中,跨平台性是一个重要的考量因素,尤其是当你需要在Windows和Linux等不同操作系统上运行同一段代码时。本示例着重讲解如何利用C++标准库中的互斥锁(mutex)和条件变量(condition variable)进行线程...

    跨平台c++日志类log

    - **可移植性**:由于C++标准库没有内置的日志机制,跨平台的日志类通常需要处理不同操作系统上的I/O差异。这个"log"类应该能够在Windows、Linux、macOS等操作系统上工作。 - **灵活性**:日志类应提供不同的日志...

    C++设计模式:基于Qt开源跨平台开发框架

    C++是一种强大而灵活的面向对象编程语言,而Qt则是一个功能丰富的开源跨平台开发框架,它为C++提供了丰富的库和工具,使得开发高质量、可移植的应用程序变得更加便捷。本文将深入探讨如何在C++中利用Qt框架实现设计...

Global site tag (gtag.js) - Google Analytics