c++的c++多线程编程视频问题

《C++并发编程实战》——1.3 在C++中使用并发和多线程
《C++并发编程实战》——1.3 在C++中使用并发和多线程
本节书摘来自异步社区出版社《C++并发编程实战》一书中的第1章,第1.1节,作者:【美】 Anthony Williams (威廉姆斯),更多章节内容可以访问云栖社区“异步社区”公众号查看。
1.3 在C++中使用并发和多线程
通过多线程为并发提供标准化的支持对C++来说是新鲜事物。
本节书摘来自异步社区出版社《C++并发编程实战》一书中的第1章,第1.1节,作者:【美】 Anthony Williams (威廉姆斯),更多章节内容可以访问云栖社区“异步社区”公众号查看。
1.3 在C++中使用并发和多线程
通过多线程为并发提供标准化的支持对C++来说是新鲜事物。只有在即将到来的C++11标准中,你才能不依赖平台相关的扩展来编写多线程代码。为了理解新版本C++线程库中众多规则背后的基本原理,了解其历史是很重要的。
1.3.1 C++多线程历程
1998C++标准版不承认线程的存在,并且各种语言要素的操作效果都以顺序抽象机的形式编写。不仅如此,内存模型也没有被正式定义,所以对于1998 C++标准,你没办法在缺少编译器相关扩展的情况下编写多线程应用程序。
当然,编译器供应商可以自由地向语言添加扩展,并且针对多线程的C API的流行——例如在POSIX C和Microsoft Windows API中的那些——导致很多C++编译器供应商通过各种平台相关的扩展来支持多线程。这种编译器支持普遍地受限于只允许使用该平台相应的C API以及确保该C++运行时库(例如异常处理机制的代码)在多线程存在的情况下运行。尽管极少有编译器供应商提供了一个正式的多线程感知内存模型,但编译器和处理器的实际表现也已经足够好,以至于大量的多线程的C++程序已被编写出来。
由于不满足于使用平台相关的C API来处理多线程,C++程序员曾期望他们的类库提供面向对象的多线程工具。像MFC这样的应用程序框架,以及像Boost和ACE这样的C++通用类库曾积累了多套C++类,封装了下层的平台相关API并提供高级的多线程工具以简化任务。各类库的具体细节,特别是在启动新线程的方面,存在很大差异,但是这些类的总体构造存在很多共通之处。有一个为许多C++类库共有的,同时也是为程序员提供很大便利的特别重要的设计,就是带锁的资源获得即初始化(RAII, ResourceAcquisitionIsInitialization)的习惯用法,来确保当退出相关作用域的时候互斥元被解锁。
许多情况下,现有的C++编译器所提供的多线程支持,例如Boost和ACE,综合了平台相关API以及平台无关类库的可用性,为编写多线程C++代码提供一个坚实的基础,也因此大约有数百万行C++代码作为多线程应用程序的一部分而被编写出来。但缺乏标准的支持,意味着存在缺少线程感知内存模型从而导致问题的场合,特别是对于那些试图通过使用处理器硬件能力来获取更高性能,或是编写跨平台代码,但是在不同平台之间编译器的实际表现存在差异。
1.3.2 新标准中的并发支持
所有这些都随着新的C++11标准的发布而改变了。不仅有了一个全新的线程感知内存模型,C++标准库也被扩展了,包含了用于管理线程(参见第2章)、保护共享数据(参见第3章)、线程间同步操作(参见第4章)以及低级原子操作(参见第5章)的各个类。
新的C++线程库很大程度上基于之前通过使用上文提到的C++类库而积累的经验。特别地,Boost线程库被用作新类库所基于的主要模型,很多类与Boost中的对应者共享命名和结构。在新标准演进的过程中,这是个双向流动,Boost线程库也改变了自己,以便在多个方面匹配C++标准,因此从Boost迁移过来的用户将会发现自己非常适应。
正如本章开篇提到的那样,对并发的支持仅仅是新C++标准的变化之一,此外还存在很多对于编程语言自身的改善,可以使得程序员们的工作更便捷。这些内容虽然不在本书的论述范围之内,但是其中的一些变化对于线程库本身及其使用方式已经形成了直接的冲击。附录A对这些语言特性做了简要的介绍。
C++中对原子操作的直接支持,允许程序员编写具有确定语义的高效代码,而无需平台相关的汇编语言。这对于那些试图编写高效的、可移植代码的程序员们来说是一个真正的福利。不仅有编译器可以搞定平台的具体内容,还可以编写优化器来考虑操作的语义,从而让程序作为一个整体得到更好的优化。
1.3.3 C++线程库的效率
对于C++整体以及包含低级工具的C++类——特别是在新版C++线程库里的那些,参与高性能计算的开发者常常关注的一点就是效率。如果你正寻求极致的性能,那么理解与直接使用底层的低级工具相比,使用高级工具所带来的实现成本,是很重要的。这个成本就是抽象惩罚(abstractionpenalty)。
C++标准委员会在整体设计C++标准库以及专门设计标准C++线程库的时候,就已经十分注重这一点了。其设计的目标之一就是在提供相同的工具时,通过直接使用低级API就几乎或完全得不到任何好处。因此该类库被设计为在大部分平台上都能高效实现(带有非常低的抽象惩罚)。
C++标准委员会的另一个目标,是确保C++能提供足够的低级工具给那些希望与硬件工作得更紧密的程序员,以获取终极性能。为了达到这个目的,伴随着新的内存模型,出现了一个全面的原子操作库,用于直接控制单个位、字节、线程间同步以及所有变化的可见性。这些原子类型和相应的操作现在可以在很多地方加以使用,而这些地方以前通常被开发者选择下放到平台相关的汇编语言中。使用了新的标准类型和操作的代码因而具有更佳的可移植性,并且更易于维护。
C++标准库也提供了更高级别的抽象和工具,它们使得编写多线程代码更简单和不易出错。有时候运用这些工具确实会带来性能成本,因为必须执行额外的代码。但是这种性能成本并不一定意味着更高的抽象惩罚;总体来看,这种性能成本并不比通过手工编写等效的函数而招致的成本更高,同时编译器可能会很好地内联大部分额外的代码。
在某些情况下,高级工具提供超出特定使用需求的额外功能。在大部分情况下这都不是问题,你没有为你不使用的那部分买单。在罕见的情况下,这些未使用的功能会影响其他代码的性能。如果你更看重程序的性能,且代价过高,你可能最好是通过较低级别的工具来手工实现需要的功能。在绝大多数情况下,额外增加的复杂性和出错的几率远大于小小的性能提升所带来的潜在收益。即使有证据确实表明瓶颈出现在C++标准库的工具中,这也可能归咎于低劣的应用程序设计而非低劣的类库实现。例如,如果过多的线程竞争一个互斥元,这将会显著影响性能。与其试图在互斥操作上花掉一点点的时间,还不如重新构造应用程序以减少互斥元上的竞争来得划算。设计应用程序以减少竞争会在第8章中加以阐述。
在非常罕见的情况下,C++标准库不提供所需的性能或行为,这时则有必要运用特定的平台相关的工具。
1.3.4 平台相关的工具
虽然C++线程库为多线程和并发处理提供了颇为全面的工具,但是在所有的平台上,都会有些额外的平台相关工具。为了能方便地访问那些工具而又不用放弃使用标准C++线程库带来的好处,C++线程库中的类型可以提供一个·native_handle()·成员函数,允许通过使用平台相关API直接操作底层实现。就其本质而言,任何使用·native_handle()·执行的操作是完全依赖于平台的,这也超出了本书(同时也是标准C++库本身)的范围。
当然,在考虑使用平台相关的工具之前,明白标准库能够提供什么是很重要的,那么让我们通过一个例子来开始。
用云栖社区APP,舒服~
【云栖快讯】Apache旗下顶级开源盛会 HBasecon Asia 2018将于8月17日在京举行,现场仅600席,免费赠票领取入口&&
文章14015篇
提供一种性能卓越、稳定、安全、便捷的计算服务,帮助您快速构建处理能力出色的应用,解放计算给服...
Node.js 性能平台(Node.js Performance Platform)是面向中...
是将源站内容分发至全国所有的节点,缩短用户查看对象的延迟,提高用户访问网站的响应速度与网站的...
为您提供简单高效、处理能力可弹性伸缩的计算服务,帮助您快速构建更稳定、安全的应用,提升运维效...
阿里云总监课正式启航C++多线程编程入门及范例详解_百度文库
您的浏览器Javascript被禁用,需开启后体验完整功能,
享专业文档下载特权
&赠共享文档下载特权
&100W篇文档免费专享
&每天抽奖多种福利
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
C++多线程编程入门及范例详解
&&介绍多线程编程方法,给出相应例程,并作出详细注解
阅读已结束,下载本文需要
定制HR最喜欢的简历
下载文档到电脑,同时保存到云知识,更方便管理
加入VIP
还剩26页未读,
定制HR最喜欢的简历
你可能喜欢C++多线程编程.pdf
扫描二维码,下载文件到手机
相关文档推荐
当前文件信息
浏览:3012次
下载:821次
您的VIP会员已过期,是否续费?
用户应遵守著作权法,尊重著作权人合法权益,不违法上传、存储并分享他人作品。举报邮箱:
京网文[0号 京ICP证100780号为了账号安全,请及时绑定邮箱和手机
点击这里,将文章分享到自己的动态
C/C++11 -- 多线程编程
C/C++ 多线程
环境:Windows, Visual Studio 2015
#include "stdafx.h"
#include &thread& //thread 头文件,实现了有关线程的类
#include &iostream&
void t1_run() {
// 线程1:循环1000次并输出"线程1正在运行"
for (int i = 0; i & 1000; i++)
std::cout && "线程1正在运行" && std::
void t2_run() {
// 线程2:循环1000次并输出"线程2正在运行"
for (int i = 0; i & 1000; i++)
std::cout && "线程2正在运行" && std::
int main()
// 创建两个线程对象,将要运行的函数作为参数
std::thread t1(t1_run);
std::thread t2(t2_run);
// join()函数,运行线程.
t1.join();
t2.join();
Output: 两个线程交替运行
Step 1: 引入thread头文件
Step 2:编写一个或多个函数(void返回值)
Step 3:创建线程对象,std::thread()
Step 4:运行线程,join()
若觉得本文不错,就分享一下吧!
评论加载中...
相关文章推荐
正在加载中
作者相关文章在Windows的多线程编程中,创建线程的函数主要有CreateThread和_beginthread(及_beginthreadex)。
&CreateThread 和 ExitThread&&& 使用API函数CreateThread创建线程时,其中的线程函数原型:& DWORD WINAPI ThreadProc(LPVOID lpParameter);在线程函数返回后,其返回值用作调用ExitThread函数的参数(由系统隐式调用)。可以使用GetExitCodeThread函数获得该线程函数的返回值。&&& 当线程函数的起始地址无效(或者不可访问)时,CreateThread函数仍可能成功返回。如果该起始地址无效,则当线程运行时,异常将发生,线程终止。并返回一个错误代码。&&& 使用CreateThread创建的线程具有THREAD_PRIORITY_NORMAL的线程优先级。可以使用GetThreadPriority和SetThreadPriority函数获取和设置线程优先级值。&&& 系统中的线程对象一直存活到线程结束,并且所有指向它的句柄都通过调用CloseHandle关闭后。&_beginthread 和 _endthread (_beginthread & _endthread)&&& 对于使用C运行时库里的函数的线程应该使用_beginthread和_endthread这些C运行时函数来管理线程,而不是使用CreateThread和ExitThread。否则,当调用ExitThread后,可能引发内存泄露。&&& 在使用_beginthread或者_beginthreadex创建线程时,应该包含头文件&process.h&,并且需要设置多线程版 本的运行时库。「Project Settings」--& 「C/C++」--&「Category」--&「Code Generation」--&「Use Run-Time Library」--&「Multithreaded」和「Debug Multithreaded」。这相当于给编译添加了一个编译选项/MT,使编译器在编译时在.obj文件中使用libcmt.lib文件名而不是 libc.lib。连接器使用这个名字与运行时库函数连接。&&& 可以调用_endthread和_endthreadex显示式结束一个线程。然而,当线程函数返回时,_endthread和_endthreadex 被自动调用。endthread和_endthreadex的调用有助于确保分配给线程的资源的合理回收。_endthread自动地关闭线程句柄,然而 _endthreadex却不会。因此,当使用_beginthread和_endthread时,不需要显示调用API函数CloseHandle式关 闭线程句柄。该行为有别于API函数ExitThread的调用。_endthread和_endthreadex回收分配的线程资源后,调用 ExitThread。&&&& 当_beginthread和_beginthreadex被调用时,操作系统自己处理线程栈的分配。如果在调用这些函数时,指定栈大小为0,则操作系统 为该线程创建和主线程大小一样的栈。如果任何一个线程调用了abort、exit或者ExitProcess,则所有线程都将被终止。
&&& 线程是操作系统管理的一种资源,不同操作系统差异很大,有的支持,有的不支持,实现的方式也不同,下面是引用的LINUX下多线程例子,使用pthread库(第三方库),简单说明下:/*thread_example.c : c multiple thread programming in linux& *author : falcon& *date : & *e-mail : [email]tunzhj03@st.lzu.edu.cn[/email]& */#include &pthread.h&#include &stdio.h&#include &sys/time.h&#define MAX 10pthread_t thread[2]; //创建线程函数返回类型pthread_mutex_ //互斥锁类型int number=0,void *thread1() //线程函数{& printf ("thread1 : I'm thread 1\n");& &&& for (i = 0; i & MAX; i++)& { &&& printf("thread1 : number = %d\n",number); &&& pthread_mutex_lock(&mut); //加锁,用于对共享变量操作& number++;& pthread_mutex_unlock(&mut); //解锁& sleep(2);& } &&& &&& printf("thread1 :主函数在等我完成任务吗?\n");& pthread_exit(NULL);}void *thread2(){& printf("thread2 : I'm thread 2\n");& &&& for (i = 0; i & MAX; i++)& { &&& printf("thread2 : number = %d\n",number);& pthread_mutex_lock(&mut);& number++;& pthread_mutex_unlock(&mut);& sleep(3);& } &&& &&& printf("thread2 :主函数在等我完成任务吗?\n");& pthread_exit(NULL);}void thread_create(void){& /*创建线程*/& pthread_create(&thread[0], NULL, thread1, NULL);& printf("线程1被创建\n");& pthread_create(&thread[1], NULL, thread2, NULL);& printf("线程2被创建\n");}void thread_wait(void){& /*等待线程结束*/& pthread_join(thread[0],NULL);& printf("线程1已经结束\n");& pthread_join(thread[1],NULL);& printf("线程2已经结束\n");}int main(){& /*用默认属性初始化互斥锁*/& pthread_mutex_init(&mut,NULL);&&& &&& printf("我是主函数哦,我正在创建线程,呵呵\n");& thread_create();& printf("我是主函数哦,我正在等待线程完成任务阿,呵呵\n");& thread_wait();& &&& return 0;}
pthread相关:
运行之前需要做一些配置:&1.下载PTHREAD的WINDOWS开发包 pthreads-w32-2-4-0-release.exe(任何一个版本均可)&&& http://sourceware.org/pthreads-win32/ ,解压到一个目录。&2.找到include和lib文件夹,下面分别把它们添加到VC++6.0的头文件路径和静态链接库路径下面:&&& a).Tools-&Options,选择Directory页面,然后在Show directories for:中选择Include files(默认)&&&& 在Directories中添加include的路径。在Show directories for:中选择Library files,&&&& 在Directories中添加lib的路径。&&& b).Project-&Settings,选择Link页面,然后将lib下的*.lib文件添加到Object/library Modules,&&&&& 各lib文件以空格隔开。&&& c).将lib下的*.dll文件复制到工程目录下,即根目录。&
1.#include &stdio.h&
2.#include &stdlib.h&
3.#include &pthread.h&
4.#include &windows.h&
piao = 100;
8.pthread_mutex_
10.void* tprocess1(void* args){
int a = 0;
while(true){
pthread_mutex_lock(&mut);
if(piao&0){
printf("窗口1----------------还剩%d张票\n",piao);
pthread_mutex_unlock(&mut);
if(a == 1) {
return NULL;
31.void* tprocess2(void* args){
int a = 0;
while(true){
pthread_mutex_lock(&mut);
if(piao&0){
printf("窗口2----------------还剩%d张票\n",piao);
pthread_mutex_unlock(&mut);
if(a == 1) {
return NULL;
52.void* tprocess3(void* args){
int a = 0;
while(true){
pthread_mutex_lock(&mut);
if(piao&0){
printf("窗口3----------------还剩%d张票\n",piao);
pthread_mutex_unlock(&mut);
if(a == 1) {
return NULL;
74.void* tprocess4(void* args){
int a = 0;
while(true){
pthread_mutex_lock(&mut);
if(piao&0){
printf("窗口4----------------还剩%d张票\n",piao);
pthread_mutex_unlock(&mut);
if(a == 1) {
return NULL;
97.int main(){
pthread_mutex_init(&mut,NULL);
pthread_t t1;
pthread_t t2;
pthread_t t3;
pthread_t t4;
pthread_create(&t4,NULL,tprocess4,NULL);
pthread_create(&t1,NULL,tprocess1,NULL);
pthread_create(&t2,NULL,tprocess2,NULL);
pthread_create(&t3,NULL,tprocess3,NULL);
Sleep(5000);
阅读(...) 评论()
我是来自厦门的Jilon. 翁,请关注我的微博:真实的weng,或关注微信:Jilon}

我要回帖

更多关于 c++面向对象多线程编程 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信