多核程序设计

上传人:da****ge 文档编号:242983098 上传时间:2024-09-13 格式:PPT 页数:78 大小:1.49MB
返回 下载 相关 举报
多核程序设计_第1页
第1页 / 共78页
多核程序设计_第2页
第2页 / 共78页
多核程序设计_第3页
第3页 / 共78页
点击查看更多>>
资源描述
,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,多核程序设计,Multi-core Programming,提 纲,线程,多线程编程的问题,Windows,多线程编程技术,1.,多核、多处理器系统中的每颗处理器(每个核),同时间内可以执行各自不同的进程(或线程)。,2.,一颗单线程能力的处理器(一个核)只能执行一个进程,双核处理器就能够同时执行两个不同的进程(或线程),四核就可以同时不同的四个进程(或线程)。,3.,倘若是执行不支持多线程的程序,那么每颗处理器内的多线程功效就无从发挥。,4,、硬件条件已经具备,但作为人机交互的操作系统和应用软件需要研究它的并行化方法,最大限度挖掘系统的整体性能。,多核与多线程编程,多核与多线程编程,发挥软件作用,充分利用系统(,CPU,)资源,提高使用效率,欲说线程,先从进程(,Process,)说起,进程,是操作系统结构的基础;是一个正在执行的程序,是计算机中正在运行的程序实例,是可以分配给处理器并由处理器执行的一个实体;由单一顺序的执行显示,一个当前状态和一组相关的系统资源所描述的活动单元。,进程为应用程序的运行实例,是应用程序的一次动态执行。我们可以简单地理解为:它是操作系统当前运行的执行程序。,对,应用程序,来说,进程就像一个大容器。在应用程序被运行后,就相当于将应用程序装进容器里了,你可以往容器里加其他东西,(,如,:,应用程序在运行时所需的变量数据、需要引用的,DLL,文件等,),,当应用程序被运行两次时,容器里的东西并不会被倒掉,系统会找一个新的进程容器来容纳它。,多线程的概念,线程(,thread,)是进程上下文(,context,)中执行的代码序列,是进程中的一个实体,是被系统独立调度和分派的基本单位 ,又被称为轻量级进程(,light weight process,),在支持多线程的系统中,进程成为资源分配和保护的实体,而线程是被调度执行的基本单元。,线程自己,不拥有,系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。,线程是程序中一个单一的顺序控制流程。在单个程序中同时运行多个线程完成不同的工作,称为多线程。,进程与线程的关系,程序在操作系统中作为进程方式存在、获取资源、运行。,在一个进程内,线程可以创建其它线程。每个线程有各自的栈,(stack),。,一个进程内所有的线程共享代码段和数据段。,进程,一个进程内的线程示例,对于在一个进程内的线程:,一个线程对共享的系统资源进行修改,在这个进程内的其它线程也可以见到这种修改。,进程内的多个线程可以对同一个内存单元进行读和写操作,所以必须要采取显式同步机制。,在同一个进程的地址空间下,线程间的通信消耗更小。,线程的状态,线程的状态,就绪(,ready,):线程等待可用的处理器。,运行(,running,):线程正在被执行。,阻塞(,blocked,):线程正在等待某个事件的发生(比如,I/O,的完成,试图加锁一个被上锁的互斥量)。,终止(,terminated,):线程从起始函数中返回或者调用,pthread_exit,。,多线程编程的问题,多核与线程并行的关系,在单核平台上的线程并发,:,在各个核上可以实现线程并行,:,CPU,核,核,1,核,2,线程的同步,由于线程共享同一进程的内存空间,多个线程可能需要同时访问同一个数据。如果没有正确的保护措施,对共享数据的访问会造成数据的不一致和错误。,全局变量是线程间通信最常用的手段,然而却容易造成访问冲突。,常用的同步机制:,互斥,(mutual exclusion),条件同步,(condition synchronization),线程的本地存储(,thread local storage, tls,),线程同步问题示例,一个银行系统中有两个线程执行取款操作,一个使用,ATM,机,另一个使用存折在柜台取款。会怎样?,如果不加以控制,会使得账户余额为负数。,互斥和同步,互斥,是指对于共享的操作系统资源(广义的资源,譬如全局变量),在各线程访问时的排它性。,临界区(,critical section,),锁(,lock,),/,互斥量(,mutex,),信号量(,semaphore,),同步,是指线程间的一种制约关系,一个线程的执行依赖另一个线程的消息。当它没有得到消息时应等待,直到消息到达时被唤醒。,事件(,event,),信号量(,semaphore,),临界区,(1),示例,int Global_Sum;,DWORD WINAPI threadFunc(LPVOID arg),int mySum=bigCompute();,Global_Sum+=mySum;,return 0;,void main(),Global_Sum=0;,for(int i=0;i0,时有信号,即当前资源的数量,0,,信号量有效。,0,时无信号,即当前资源的数量是,0,,信号量无效。,系统不允许当前资源的数量为负值,即不能在信号量为负的情况下执行任务。,V,操作时也不能超过最大值。,核心对象,可以跨进程访问。,信号量,(2),示例,保护共享资源,DWORD WINAPI threadFunc(LPVOID arg),int mySum=bigCompute();,Global_Sum+=mySum;,return 0;,DWORD WINAPI threadFunc(LPVOID arg),int mySum=bigCompute();,Global_Sum+=mySum;,return 0;,thread1,thread2,Semaphore sem(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(LPVOID arg),int mySum1=bigCompute();,Global_Sum+=mySum1;,return 0;,thread_Consumer(LPVOID arg),int mySum2;,mySum2*=Global_Sum;,return 0;,thread1,thread2,Semaphore sem(0); /,创建信号量变量,sem,,并设其初值为,0,P(sem); /,若,sem0,sem,减,1,V(sem); /sem,加,1,并判断,运算次序:,mySum2=(Global_Sum+mySum1)*mySum2,事件,(Event)(1),作用:同步线程,用事件(,Event,)来同步线程最具弹性(灵活),一个事件有两种状态:激发状态和未激发状态。也称有信号状态和无信号状态。,事件类型,手动重置事件,手动重置事件被设置为激发状态后,会唤醒所有等待的线程,而且一直保持为激发状态,直到程序重新把它设置为未激发状态。,自动重置事件,自动重置事件被设置为激发状态后,会唤醒,“,一个,”,等待中的线程,然后自动恢复为未激发状态。所以用自动重置事件来同步两个线程比较理想。,事件,(2),示例,“,读,-,写,”,线程同步,Void ReadThread(LPVOID p),coutGlobalSumendl;,Void WriteThread(LPVOID p),GlobalSum+;,int main(),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);,HANDLE evRead,evFinish;,线程的本地存储,(TLS),TLS,为每个线程维护一个与该线程绑定的变量的副本,从而隔离了多个线程的数据。,JAVA,中的支持,Java.lang.ThreadLocal,并行(多线程)程序设计方法,显式线程(,Explicit threading,),微软,Windows,线程,API, Pthreads, Java,线程类等。,利用编译器指导(,Compiler-directed,),自动并行, OpenMP, Intel Threading Building Blocks,等,利用并行应用库(,Parallel libraries,),Intel IPP/MKL, ScaLAPACK, PARDISO, PLAPACK,并行程序语言,有,150,种以上,消息传递(,Message passing,),MPI, OpenMP, PVM,等等。,串行程序并行化(多线程)一般流程,分析,VTune Performance Analyzer,可并行性分析,设计,(Introduce Threads),Intel Performance libraries: IPP and MKL,OpenMP* (Intel Compiler),Explicit threading (Win32*, Pthreads*),调试错误,Intel Thread Checker,Intel Debugger,性能分析和调整,Intel Thread Profiler,VTune Performance Analyzer,Windows,环境下的多线程编程,Windows,线程库介绍,Win32 API,Windows,操作系统为内核以及应用程序之间提供的接口,将内核提供的功能进行函数封装,应用程序通过调用相关的函数获得相应的系统功能。,MFC,微软基础函数类库,(Microsoft Foundation Classes),,由微软提供的,用类库的方式将,Win32 API,进行封装,以类的方式提供给开发者。,AfxBeginThread(Threadfunc,hWnd,THREAD_PRIORITY_NORMAL),Windows,线程库介绍,.NET,Framework,由两部分构成:公共语言运行库(,Common,Language,Runtime,,,CLR,)和,Framework,类库(,Framework,Class,Library,,,FCL,)。,.NET,基础类库的,System.Threading,命名空间提供了大量的类和接口来支持多线程。所有与多线程机制相关的类都存放在,System.Threading,命名空间中。,使用,win32,线程,API,Win32,函数库中提供了操作多线程的函数,包括创建线程、管理线程、终止线程、线程同步等接口。,线程函数,DWORD WINAPI ThreadFunc (LPVOID lpvThreadParm),;,线程创建,HANDLE CreateThread,(,LPSECURITY_ATTRIBUTES lpThreadAttributes,SIZE_T dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId,);,也可以用,_beginthread,(,多线程函数名,0,NULL) /,须引入”,process.h,”,使用,win32,线程,APIHANDLE,Windows,中的句柄实际上是一个唯一的数字,它引用一个,Windows,对象,例如窗口或者图标等。,句柄是一种指向指针的东西,。我们知道,所谓指针是一种内存地址。应用程序启动后,组成这个程序的各对象是驻留在内存的。如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址 访问对象。但是,如果真的这样认为,那么就大错特错了。,Windows,是一个以虚拟内存为基础的操作系统。在这种系统环境下,,Windows,内存管理器经常在内存中来回移动对象,依此来满足各种应用程序的内存需要。对象被移动意味着它的地址变化了,如果地址总是如此变化,我们该到哪里去找该对象呢,?,为了解决这个问题,,Windows,操作系统为各应用程序腾出一些内存储地址,用来专门登记各应用对象在内存中的地址变化,而这个地址,(,存储单元的位置,),本身是不变的。,可以简单的把句柄看邮箱,即使住处变了,由于邮箱不变,人们仍然可以寄信,邮局记录这些句柄的对应关系。,使用,win32,线程,APIHANDLE,Windows,内存管理器在移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来保存。这样我们只需记住这个句柄地址就可以间接地知道对象具体在内存中的哪个位置。这个地址是在对象装载,(Load),时由系统分配给的,当系统卸载时,(Unload),又释放给系统。,句柄地址,(,稳定,),记载着对象在内存中的地址对象在内存中的地址,(,不稳定,),实际对象,但是,必须注意的是程序每次重新启动,系统不能保证分配给这个程序的句柄还是原来的那个句柄,而且绝大多数情况的确不一样的。假如我们把进入电影院看电影看成是一个应用程序的启动运行,那么系统给应用程序分配的句柄总是不一样,这和每次电影院售给我们的门票总是不同的一个座位是一样的道理。,使用,WIN32,线程,API ,线程函数,MyThreadStart(LPVOID p),即为线程的执行函数,线程函数,CreateThread,的参数,lpThreadAttribute,This is optional security for child processes. It can be,NULL,.,dwStackSize,This is stack size in bytes. It can be,0, which means use default (usually 1 megabyte).,lpStartAddress,This is a globally visible function declared DWORD WINAPI. This is,the,function,for the thread to begin execution.,lpParameter,This is,a pointer,to the one parameter for lpStartAddress function. Use a pointer to a structure to pass multiple parameters.,dwCreationFlags,This creates a thread and starts or suspends it. Use,0,to start; otherwise use CREATE_SUSPENDED.,lpThreadId,This is an output parameter and returns a unique (across the system) integer for the thread. It can be,NULL,.,线程的管理,设置线程的优先级,线程优先级,=,进程优先级,+,线程相对优先级,Bool SetThreadPriority (HANDLE hThread , int nPriority),线程的挂起与恢复,进程中的每个线程都有挂起计数器,(suspend count),。当挂起计数器值为,0,时,线程被执行;当挂起计数器值大于,0,时,调度器不去调度该线程。,DWORD SuspendThread(HANDLE hThread),;,DWORD ResumeThread(HANDLE hThread),;,线程终结,VOID ExitThread( DWORD dwExitCode);,线程的等待和退出,线程间的等待,一组能使线程阻塞其自身执行的等待函数,WaitForSingleObject,、,WaitForMultipleObject,。,释放操作系统资源,在程序结束前要清除线程及其所占资源,线程退出调用函数:,BOOL CloseHandle(HANDLE,hObject,);,多线程基础,示例分析,多线程基础,示例分析(方案一),Waiting for a Thread,Wait for one object (thread),Calling thread waits (blocks) until, Time expires, Return code used to indicate this, Thread exits (handle is signaled), Use,INFINITE,to wait until thread termination,Does not use CPU cycles,Waiting for,Many,Threads,Wait for up to 64 objects (threads),Wait for all:,fWaitAll=TRUE,Wait for any:,fWaitAll=FALSE,Return value is first array index found,Example: Multiple Threads,Modify the previous example code to print out, Appropriate “,Hello Thread,” message, Unique thread number, Use for-loop variable of,CreateThread,loop,Sample output:,Example 2: Hello Threads,Example 2: Hello Threads,Whats wrong?,What is printed for myNum?,Hello Threads Timeline,程序中出现了“数据竞争”,soft error,!,数据竞争(,Race Conditions,),Concurrent access of same variable by multiple threads, Read/Write conflict, Write/Write conflict,Most common error in concurrent programs,May not be apparent at all times,How to Avoid Data Races,Scope variables to be local to threads, Variables declared within threaded functions, Allocate on threads stack, TLS (Thread Local Storage),Control shared access with critical regions, Mutual exclusion and synchronization, Lock, semaphore, event, critical section, mutex,程序修改方案,Solution “Local” Storage,多线程编程举例(示例一),/ exa1.cpp : function,_beginthread(,fun,0,NULL,),.,#include stdafx.h,#include ,#include ,#include ,#include ,using namespace std; /,保证标准屏幕输入,/,输出语句的使用,void ThreadFunc1(PVOID param),while(1),Sleep(1000);,coutThis is ThreadFunc1endl;,void ThreadFunc2(PVOID param), while(1),Sleep(1000);,coutThis is ThreadFunc2endl;,int main() /,主函数, int i=0;,/ Should be add in main code body,#ifdef _INTEL_COMPILER,printf(_INTEL_COMPILER = %dn, _INTEL_COMPILER);,#else,printf(_INTEL_COMPILER is not defined.n);,#endif,_beginthread(ThreadFunc1,0,NULL); /,_beginthread(ThreadFunc2,0,NULL);,Sleep(3000);,coutendendl;,return 0;,多线程编程举例(示例一),#include ,#include ,using namespace std;,DWORD WINAPI FunOne(LPVOID param), while(true),Sleep(1000);,couthello! ;,return 0;,DWORD WINAPI FunTwo(LPVOID param), while(true),Sleep(1000);,coutinput;,if(input=1) ResumeThread(hand1); ResumeThread(hand2); ,if(input=0) SuspendThread(hand1); SuspendThread(hand2); ,if(input=2) return 0; ,;,TerminateThread(hand1,1);,TerminateThread(hand2,1);,return 0; ,多线程编程举例(示例二),#include stdafx.h,#include ,#include ,using namespace std;,int globalvar = false;,DWORD WINAPI ThreadFunc(LPVOID pParam),coutThreadFuncendl;,Beep(5000,2000); / beep and Sleep(200);,globalvar = true;,return 0;,int main(), /,首先创建新线程,HANDLE hthread = CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL);,if (!hthread),coutThread Create Error ! endl;,CloseHandle(hthread);,while (!globalvar),cout“Thread while”endl; /,主线程运行,coutThread exit 0,Increment semaphore (Post operation), Increase semaphore count by,cReleaseCount, Returns the previous count through,lpPreviousCount,Win32,线程同步的实现,Semaphore,(举例),Main thread opens input file, waits for thread termination,Threads will Read line from input file Count all five-letter words in line,Win32,线程同步的实现,Semaphore,(举例续),Main thread opens input file, waits for thread termination,Threads will Read line from input file Count all five-letter words in line,MFC,线程编程及同步的实现,AfxBeginThread(),来创建一个,CWinThread,对象。,CWinThread:CreateThread(),函数用来启动新的线程,MFC,同步类,CCriticalSection,只允许当前进程中的一个线程访问某个对象的同步类,CMutes,只允许系统中一个进程内的一个线程访问某个对象的同步类,CSymaphore,只允许一到某个指定数目个线程同时访问某个对象的同步类,CEvent,当某个事件发生时通知一个应用程序的同步类,微软,.NET,框架的线程,API,通用语言运行时,(,Common Language Runtime: CLR,),微软,2002,年引入的一种新的执行环境。,C#,.NET,框架、,CLR,以及程序执行所需要的工具合起来,称为“,.NET”,。,内容,创建,管理,线程池,同步,上机实习二,将串行的积分法计算,PI,值程序改进成多线程的程序;,解决同步问题;,矩形法则的数值积分方法估算,Pi,的值,Pi,值计算,Pi,值计算,多线程提高计算速度,利用所学到的,Windows,多线程编程方法改进该串行计算方法,实现算法并行化处理。,提示:,1,、循环体能否分割?,2,、哪些变量可以本地化或全局化,3,、哪些变量需要所有的线程所共享,To be continued,。,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 小学资料


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!