




已阅读5页,还剩73页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
.,多核程序设计Multi-coreProgramming,.,提纲,线程多线程编程的问题Windows多线程编程技术,.,1.多核、多处理器系统中的每颗处理器(每个核),同时间内可以执行各自不同的进程(或线程)。2.一颗单线程能力的处理器(一个核)只能执行一个进程,双核处理器就能够同时执行两个不同的进程(或线程),四核就可以同时不同的四个进程(或线程)。3.倘若是执行不支持多线程的程序,那么每颗处理器内的多线程功效就无从发挥。4、硬件条件已经具备,但作为人机交互的操作系统和应用软件需要研究它的并行化方法,最大限度挖掘系统的整体性能。,多核与多线程编程,.,多核与多线程编程,发挥软件作用,充分利用系统(CPU)资源,提高使用效率,.,欲说线程,先从进程(Process)说起,进程是操作系统结构的基础;是一个正在执行的程序,是计算机中正在运行的程序实例,是可以分配给处理器并由处理器执行的一个实体;由单一顺序的执行显示,一个当前状态和一组相关的系统资源所描述的活动单元。进程为应用程序的运行实例,是应用程序的一次动态执行。我们可以简单地理解为:它是操作系统当前运行的执行程序。对应用程序来说,进程就像一个大容器。在应用程序被运行后,就相当于将应用程序装进容器里了,你可以往容器里加其他东西(如:应用程序在运行时所需的变量数据、需要引用的DLL文件等),当应用程序被运行两次时,容器里的东西并不会被倒掉,系统会找一个新的进程容器来容纳它。,.,多线程的概念,线程(thread)是进程上下文(context)中执行的代码序列,是进程中的一个实体,是被系统独立调度和分派的基本单位,又被称为轻量级进程(lightweightprocess)在支持多线程的系统中,进程成为资源分配和保护的实体,而线程是被调度执行的基本单元。线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。线程是程序中一个单一的顺序控制流程。在单个程序中同时运行多个线程完成不同的工作,称为多线程。,.,进程与线程的关系,程序在操作系统中作为进程方式存在、获取资源、运行。在一个进程内,线程可以创建其它线程。每个线程有各自的栈(stack)。一个进程内所有的线程共享代码段和数据段。,进程,.,一个进程内的线程示例,对于在一个进程内的线程:一个线程对共享的系统资源进行修改,在这个进程内的其它线程也可以见到这种修改。进程内的多个线程可以对同一个内存单元进行读和写操作,所以必须要采取显式同步机制。在同一个进程的地址空间下,线程间的通信消耗更小。,.,线程的状态,线程的状态就绪(ready):线程等待可用的处理器。运行(running):线程正在被执行。阻塞(blocked):线程正在等待某个事件的发生(比如I/O的完成,试图加锁一个被上锁的互斥量)。终止(terminated):线程从起始函数中返回或者调用pthread_exit。,.,多线程编程的问题,.,多核与线程并行的关系,在单核平台上的线程并发:在各个核上可以实现线程并行:,CPU核,核1,核2,.,线程的同步,由于线程共享同一进程的内存空间,多个线程可能需要同时访问同一个数据。如果没有正确的保护措施,对共享数据的访问会造成数据的不一致和错误。全局变量是线程间通信最常用的手段,然而却容易造成访问冲突。常用的同步机制:互斥(mutualexclusion)条件同步(conditionsynchronization)线程的本地存储(threadlocalstorage,tls),.,线程同步问题示例,一个银行系统中有两个线程执行取款操作,一个使用ATM机,另一个使用存折在柜台取款。会怎样?如果不加以控制,会使得账户余额为负数。,.,互斥和同步,互斥是指对于共享的操作系统资源(广义的资源,譬如全局变量),在各线程访问时的排它性。临界区(criticalsection)锁(lock)/互斥量(mutex)信号量(semaphore)同步是指线程间的一种制约关系,一个线程的执行依赖另一个线程的消息。当它没有得到消息时应等待,直到消息到达时被唤醒。事件(event)信号量(semaphore),.,临界区(1),示例,intGlobal_Sum;DWORDWINAPIthreadFunc(LPVOIDarg)intmySum=bigCompute();Global_Sum+=mySum;return0;voidmain()Global_Sum=0;for(inti=0;i0时有信号,即当前资源的数量0,信号量有效。0时无信号,即当前资源的数量是0,信号量无效。系统不允许当前资源的数量为负值,即不能在信号量为负的情况下执行任务。V操作时也不能超过最大值。核心对象,可以跨进程访问。,.,信号量(2)示例,保护共享资源,DWORDWINAPIthreadFunc(LPVOIDarg)intmySum=bigCompute();Global_Sum+=mySum;return0;,DWORDWINAPIthreadFunc(LPVOIDarg)intmySum=bigCompute();Global_Sum+=mySum;return0;,thread1,thread2,Semaphoresem(1);/创建信号量变量sem,并设其初值为1,P(sem);/若sem0,sem减1,P(sem);/若sem0,sem减1,V(sem);/sem加1并判断,V(sem);/sem加1并判断,信号量已经小于等于0的线程会进入等待队列,关键在于P(sem)时,即减和判断期间,不允许其他线程打断,即原子操作。,.,信号量(3)示例,同步线程-生产者消费者问题,thread_producer(LPVOIDarg)intmySum1=bigCompute();Global_Sum+=mySum1;return0;,thread_Consumer(LPVOIDarg)intmySum2;mySum2*=Global_Sum;return0;,thread1,thread2,Semaphoresem(0);/创建信号量变量sem,并设其初值为0,P(sem);/若sem0,sem减1,V(sem);/sem加1并判断,运算次序:mySum2=(Global_Sum+mySum1)*mySum2,.,事件(Event)(1),作用:同步线程用事件(Event)来同步线程最具弹性(灵活)一个事件有两种状态:激发状态和未激发状态。也称有信号状态和无信号状态。事件类型手动重置事件手动重置事件被设置为激发状态后,会唤醒所有等待的线程,而且一直保持为激发状态,直到程序重新把它设置为未激发状态。自动重置事件自动重置事件被设置为激发状态后,会唤醒“一个”等待中的线程,然后自动恢复为未激发状态。所以用自动重置事件来同步两个线程比较理想。,.,事件(2)示例,“读-写”线程同步,VoidReadThread(LPVOIDp)coutGlobalSumendl;,VoidWriteThread(LPVOIDp)GlobalSum+;,intmain()evRead=CreateEvent(NULL,FALSE,FALSE,NULL);evFinish=CreateEvent(NULL,FALSE,FALSE,NULL);_beginthread(ReadThread,0,NULL);_beginthread(WriteThread,0,NULL);WaitForSingleObject(evFinish,INFINITE);,WaitForSingleObject(evRead,INFINITE);,SetEvent(evFinish);,SetEvent(evRead);,HANDLEevRead,evFinish;,.,线程的本地存储(TLS),TLS为每个线程维护一个与该线程绑定的变量的副本,从而隔离了多个线程的数据。JAVA中的支持Java.lang.ThreadLocal,.,并行(多线程)程序设计方法,显式线程(Explicitthreading)微软Windows线程API,Pthreads,Java线程类等。利用编译器指导(Compiler-directed)自动并行,OpenMP,IntelThreadingBuildingBlocks等利用并行应用库(Parallellibraries)IntelIPP/MKL,ScaLAPACK,PARDISO,PLAPACK并行程序语言有150种以上消息传递(Messagepassing)MPI,OpenMP,PVM,等等。,.,串行程序并行化(多线程)一般流程,分析VTunePerformanceAnalyzer可并行性分析设计(IntroduceThreads)IntelPerformancelibraries:IPPandMKLOpenMP*(IntelCompiler)Explicitthreading(Win32*,Pthreads*)调试错误IntelThreadCheckerIntelDebugger性能分析和调整IntelThreadProfilerVTunePerformanceAnalyzer,.,Windows环境下的多线程编程,.,Windows线程库介绍,Win32APIWindows操作系统为内核以及应用程序之间提供的接口,将内核提供的功能进行函数封装,应用程序通过调用相关的函数获得相应的系统功能。MFC微软基础函数类库(MicrosoftFoundationClasses),由微软提供的,用类库的方式将Win32API进行封装,以类的方式提供给开发者。AfxBeginThread(Threadfunc,hWnd,THREAD_PRIORITY_NORMAL),.,Windows线程库介绍,.NETFramework由两部分构成:公共语言运行库(CommonLanguageRuntime,CLR)和Framework类库(FrameworkClassLibrary,FCL)。.NET基础类库的System.Threading命名空间提供了大量的类和接口来支持多线程。所有与多线程机制相关的类都存放在System.Threading命名空间中。,.,使用win32线程API,Win32函数库中提供了操作多线程的函数,包括创建线程、管理线程、终止线程、线程同步等接口。线程函数DWORDWINAPIThreadFunc(LPVOIDlpvThreadParm);线程创建HANDLECreateThread(LPSECURITY_ATTRIBUTESlpThreadAttributes,SIZE_TdwStackSize,LPTHREAD_START_ROUTINElpStartAddress,LPVOIDlpParameter,DWORDdwCreationFlags,LPDWORDlpThreadId);也可以用_beginthread(多线程函数名,0,NULL)/须引入”process.h”,.,使用win32线程APIHANDLE,Windows中的句柄实际上是一个唯一的数字,它引用一个Windows对象,例如窗口或者图标等。句柄是一种指向指针的东西。我们知道,所谓指针是一种内存地址。应用程序启动后,组成这个程序的各对象是驻留在内存的。如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址访问对象。但是,如果真的这样认为,那么就大错特错了。Windows是一个以虚拟内存为基础的操作系统。在这种系统环境下,Windows内存管理器经常在内存中来回移动对象,依此来满足各种应用程序的内存需要。对象被移动意味着它的地址变化了,如果地址总是如此变化,我们该到哪里去找该对象呢?为了解决这个问题,Windows操作系统为各应用程序腾出一些内存储地址,用来专门登记各应用对象在内存中的地址变化,而这个地址(存储单元的位置)本身是不变的。可以简单的把句柄看邮箱,即使住处变了,由于邮箱不变,人们仍然可以寄信,邮局记录这些句柄的对应关系。,.,使用win32线程APIHANDLE,Windows内存管理器在移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来保存。这样我们只需记住这个句柄地址就可以间接地知道对象具体在内存中的哪个位置。这个地址是在对象装载(Load)时由系统分配给的,当系统卸载时(Unload)又释放给系统。句柄地址(稳定)记载着对象在内存中的地址对象在内存中的地址(不稳定)实际对象但是,必须注意的是程序每次重新启动,系统不能保证分配给这个程序的句柄还是原来的那个句柄,而且绝大多数情况的确不一样的。假如我们把进入电影院看电影看成是一个应用程序的启动运行,那么系统给应用程序分配的句柄总是不一样,这和每次电影院售给我们的门票总是不同的一个座位是一样的道理。,.,使用WIN32线程API线程函数,MyThreadStart(LPVOIDp)即为线程的执行函数,.,线程函数CreateThread的参数,lpThreadAttributeThisisoptionalsecurityforchildprocesses.ItcanbeNULL.dwStackSizeThisisstacksizeinbytes.Itcanbe0,whichmeansusedefault(usually1megabyte).lpStartAddressThisisagloballyvisiblefunctiondeclaredDWORDWINAPI.Thisisthefunctionforthethreadtobeginexecution.lpParameterThisisapointertotheoneparameterforlpStartAddressfunction.Useapointertoastructuretopassmultipleparameters.dwCreationFlagsThiscreatesathreadandstartsorsuspendsit.Use0tostart;otherwiseuseCREATE_SUSPENDED.lpThreadIdThisisanoutputparameterandreturnsaunique(acrossthesystem)integerforthethread.ItcanbeNULL.,.,线程的管理,设置线程的优先级线程优先级=进程优先级+线程相对优先级BoolSetThreadPriority(HANDLEhThread,intnPriority)线程的挂起与恢复进程中的每个线程都有挂起计数器(suspendcount)。当挂起计数器值为0时,线程被执行;当挂起计数器值大于0时,调度器不去调度该线程。DWORDSuspendThread(HANDLEhThread);DWORDResumeThread(HANDLEhThread);线程终结,VOIDExitThread(DWORDdwExitCode);,.,线程的等待和退出,线程间的等待一组能使线程阻塞其自身执行的等待函数WaitForSingleObject、WaitForMultipleObject。释放操作系统资源在程序结束前要清除线程及其所占资源线程退出调用函数:BOOLCloseHandle(HANDLEhObject);,.,多线程基础示例分析,.,多线程基础示例分析(方案一),.,WaitingforaThread,Waitforoneobject(thread)Callingthreadwaits(blocks)untilTimeexpiresReturncodeusedtoindicatethisThreadexits(handleissignaled)UseINFINITEtowaituntilthreadterminationDoesnotuseCPUcycles,.,WaitingforManyThreads,Waitforupto64objects(threads)Waitforall:fWaitAll=TRUEWaitforany:fWaitAll=FALSEReturnvalueisfirstarrayindexfound,.,Example:MultipleThreads,.,ModifythepreviousexamplecodetoprintoutAppropriate“HelloThread”messageUniquethreadnumberUsefor-loopvariableofCreateThreadloopSampleoutput:,Example2:HelloThreads,.,Example2:HelloThreads,Whatswrong?WhatisprintedformyNum?,.,HelloThreadsTimeline,程序中出现了“数据竞争”softerror!,.,数据竞争(RaceConditions),ConcurrentaccessofsamevariablebymultiplethreadsRead/WriteconflictWrite/WriteconflictMostcommonerrorinconcurrentprogramsMaynotbeapparentatalltimes,.,HowtoAvoidDataRaces,ScopevariablestobelocaltothreadsVariablesdeclaredwithinthreadedfunctionsAllocateonthreadsstackTLS(ThreadLocalStorage)ControlsharedaccesswithcriticalregionsMutualexclusionandsynchronizationLock,semaphore,event,criticalsection,mutex,.,程序修改方案Solution“Local”Storage,.,多线程编程举例(示例一),/exa1.cpp:function_beginthread(fun,0,NULL).#includestdafx.h#include#include#include#includeusingnamespacestd;/保证标准屏幕输入/输出语句的使用voidThreadFunc1(PVOIDparam)while(1)Sleep(1000);coutThisisThreadFunc1endl;voidThreadFunc2(PVOIDparam)while(1)Sleep(1000);coutThisisThreadFunc2endl;,.,intmain()/主函数inti=0;/Shouldbeaddinmaincodebody#ifdef_INTEL_COMPILERprintf(_INTEL_COMPILER=%dn,_INTEL_COMPILER);#elseprintf(_INTEL_COMPILERisnotdefined.n);#endif_beginthread(ThreadFunc1,0,NULL);/_beginthread(ThreadFunc2,0,NULL);Sleep(3000);coutendendl;return0;,多线程编程举例(示例一),.,#include#includeusingnamespacestd;DWORDWINAPIFunOne(LPVOIDparam)while(true)Sleep(1000);couthello!;return0;DWORDWINAPIFunTwo(LPVOIDparam)while(true)Sleep(1000);coutworld!;return0;,多线程编程举例(示例二),程序首先创建两个线程;一个线程打印hello一个线程打印world当输入为1时,执行线程否则挂起线程。,.,intmain(intargc,char*argv)intinput=0;HANDLEhand1=CreateThread(NULL,0,FunOne,(void*),多线程编程举例(示例二),.,#includestdafx.h#include#includeusingnamespacestd;intglobalvar=false;DWORDWINAPIThreadFunc(LPVOIDpParam)coutThreadFuncendl;Beep(5000,2000);/beepandSleep(200);globalvar=true;return0;intmain()/首先创建新线程HANDLEhthread=CreateThread(NULL,0,ThreadFunc,NULL,0,NULL);if(!hthread)coutThreadCreateError!endl;CloseHandle(hthread);while(!globalv
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- ACP阿里云复习测试卷附答案
- 污水处理厂地质勘察与处理方案
- 生活垃圾收集点除臭技术应用方案
- 森林修复后期抚育实施方案
- 高速公路施工扬尘治理管控方案
- 建筑垃圾源头分类指导实施方案
- 冷链区域分拨中心建设规划方案
- 免烧砖生产投产试运行方案
- 2025年圣经人物题库及答案
- 血糖理论试题及答案
- 水平定向钻进管线铺设工程技术规范
- 水利安全风险防控“六项机制”与安全生产培训
- DB44-T 2452-2023 高速公路服务设施建设规模设计规范
- 跨境电商物流风险管理-全面剖析
- 商业商场保洁合同协议
- 岩移观测施工方案
- 2025济南市厂房租赁合同
- 吹灰器维护考试题及答案
- 常见病护理常规
- IP授权合作及衍生品开发协议
- 渠道与代理商管理
评论
0/150
提交评论