可视化ppt教程 多线程.ppt_第1页
可视化ppt教程 多线程.ppt_第2页
可视化ppt教程 多线程.ppt_第3页
可视化ppt教程 多线程.ppt_第4页
可视化ppt教程 多线程.ppt_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

可视化程序设计 第7章多线程程序设计 线程与线程的创建进程和线程线程的创建线程的控制线程的挂起线程的恢复线程的终止线程的多核调用线程之间数据共享 线程同步与互斥多线程之间的竞争使用临界区对象实现线程竞争使用互斥量实现线程竞争使用信号量对象实现线程同步使用事件对象实现线程同步使用消息实现线程之间的通信 进程和线程 线程在这里分为两种 一个是工作线程 一个是用户界面线程 运行状态就是进程正在执行的状态 就绪状态就是进程等待执行的状态 阻塞状态是进程等待某一事件发生的状态 这个事件可能是输入输出的完成 也可能是其他进程完成某项任务 后面描述 进程可以从运行状态到阻塞状态是等待某一事件的发生 当等待的事件发生以后 进程就会从阻塞状态到达就绪状态 当进程运行一段时间后 到达它能够持续运行的时间后 时间片 进程就会从运行状态变为就绪状态 Windows系统进程调度使用的是优先级调度 优先级高的就会优先运行 线程的创建 线程类及其方法 VC中控制线程的类为CWinThread CWinThread类的可重载方法 线程优先级 工作线程 建立方式如下 UINTThreadWork LPVOIDpParam return0 CWinThread AfxBeginThread 线程执行体函数指针AFX THREADPROCpfnThreadProc LPVOIDpParam 向线程传递参数 线程的优先级intnPriority THREAD PRIORITY NORMAL UINTnStackSize 0 线程所占堆栈的尺寸DWORDdwCreateFlags 0 线程创建标志 线程的安全结构LPSECURITY ATTRIBUTESlpSecurityAttrs NULL pfnThreadProc是函数指针 它指向静态或一个全局函数 而这个函数就是线程的执行体 pParam是一个指针参数 它可以指向任何类型数据 如整数 句柄和结构体等 nStackSize是线程运行时使用堆栈的空间 如果为0 就是默认值1M 1M的空间对于一般的线程已经足够大了 dwCreateFlags 指定创建线程以后 线程有怎么样的标志 可以指定两个值 CREATE SUSPENDED 线程创建以后 会处于挂起状态 直到调用 ResumeThread0 创建线程后就开始运行 lpSecurityAttrs 指向一个SECURITY ATTRIBUTES的结构体 用它来标志新创建线程的安全性 如果为NULL 那么新创建的线程就具有和主线程一样的安全性 用户界面线程 使用向导可以生成用户界面线程 生成对话框作为用户界面线程的界面 建立用户界面线程CWinThread AfxBeginThread CRuntimeClass pThreadClass 用户界面线程intnPriority THREAD PRIORITY NORMAL 优先级UINTnStackSize 0 堆栈尺寸DWORDdwCreateFlags 0 线程创建标志LPSECURITY ATTRIBUTESlpSecurityAttrs NULL 线程的安全结构 线程的挂起 调用SuspendThread函数用于将线程的挂起计数加1 当线程的挂起计数大于0时 该线程将暂停执行 称之为挂起状态 SuspendThread最好在线程内部调用 这样可以知道线程什么时候停止避免引起死锁 而死锁是线程进入阻塞状态后 永远也得不到执行的一种状态 SuspendThread的返回值是挂起的计数值 如果返回 1 就会意味着发生错误 线程的恢复 调用消耗线程挂起的ResumeThread用于将线程的挂起计数减1 当线程的挂起计数等于0时 线程恢复执行 在程序设计中一般不建议使用SuspendThread和ResumeThread实现线程的操作 只是在线程创建过程中需要完成某种初始化工作 首先使线程暂停操作 然后调用ResumeThread恢复线程的运行 线程的终止 线程函数退出循环来返回通过调用ExitThread函数 线程将自行撤消voidExitThread DWORDdwExitCode 同一个进程或另一个进程中的线程调用TerminateThread函数BOOLTerminateThread HANDLEhThread 线程句柄DWORDdwExitCode 退出代码 在进程终止运行时撤消线程 线程的多核调用 DWORD PTRSetThreadAffinityMask HANDLEhThread 线程句柄DWORD PTRdwThreadAffinityMask 亲和性掩码 线程0运行在CPU0上SetThreadAffinityMask hThread0 0 x00000001 线程1 2 3运行在CPU1 CPU2 CPU3的任意一个核上SetThreadAffinityMask hThread1 0 x0000000E SetThreadAffinityMask hThread2 0 x0000000E SetThreadAffinityMask hThread3 0 x0000000E 线程之间数据共享 如在A文件中声明如下 externinta 在B文件中声明如下 inta HANDLECreateFileMapping HANDLEhFile 文件句柄LPSECURITY ATTRIBUTESlpAttributes 安全描述符DWORDflProtect 保护方式DWORDdwMaximumSizeHigh 最大尺寸的高32位DWORDdwMaximumSizeLow 最大尺寸的低32位LPCTSTRlpName 对象名 LPVOIDMapViewOfFile HANDLEhFileMappingObject 文件映射对象DWORDdwDesiredAccess 文件访问模式DWORDdwFileOffsetHigh 文件映射起点的高32位DWORDdwFileOffsetLow 文件映射起点的低32位SIZE TdwNumberOfBytesToMap 映射文件的字节数 HANDLEhMappingSend hMappingSend CreateFileMapping HANDLE 0 xFFFFFFFF NULL PAGE READWRITE 0 8 1024 SENDDATE LPSTRlpSender lpSender LPSTR MapViewOfFile hMappingSend FILE MAP ALL ACCESS 0 0 0 多线程之间的竞争 如存在两个线程TA TB和一个共享的全局变量a TA访问共享变量的程序如下 a a 1TB的如下 a a 2a的初始值为2 不论先执行TA还是TB最终a的值都应该是5 但是有的情况下并非如此 因为a a 1编译后为以下三句 regester a regester regester 1 a regester a a 2编译后为以下三句 regester a regester regester 2 a regester 使用临界区对象实现线程竞争 可以使用CCriticalSection 临界区类 实现这种互斥访问 classCCriticalSection publicCSyncObject public CCriticalSection virtualBOOLUnlock BOOLLock BOOLLock DWORDdwTimeout CCriticalSectioncriticalSection 对于TA线程While 1 criticalSection Lock a a 1 criticalSection Unlock 对于TB线程While 1 criticalSection Lock a a 2 criticalSection Unlock 使用互斥量实现线程竞争 classCMutex publicCSyncObject public CMutex BOOLbInitiallyOwn FALSE LPCTSTRlpszName NULL LPSECURITY ATTRIBUTESlpsaAttribute NULL 该类只有一个构造函数 该构造函数存在参数 bInitiallyOwn说明初始条件下 该类的对象处于锁定状态 lpszName该系统对象的名称 如果指明了该对象的名称就可以实现进程之间的共享 lpsaAttribute该对象安全描述符的属性 一般为NULL CMutexmutex 定义一个CMutex类型的全局变量 对于TA线程While 1 mutex Lock a a 1 mutex Unlock 对于TB线程While 1 mutex Lock a a 2 mutex Unlock HANDLEhMappingSend 创建内存映射文件hMappingSend CreateFileMapping HANDLE 0 xFFFFFFFF NULL PAGE READWRITE 0 4 SENDDATE 把数据映射为整数int a int MapViewOfFile hMappingSend FILE MAP ALL ACCESS 0 0 0 CMutexmutex FALSE SendMutex 生成名称为 SendMutex 的一个互斥量While 1 mutex Lock a a 1 mutex Unlock 对于TB线程HANDLEhMappingSend hMappingSend CreateFileMapping HANDLE 0 xFFFFFFFF NULL PAGE READWRITE 0 4 SENDDATE int a int MapViewOfFile hMappingSend FILE MAP ALL ACCESS 0 0 0 CMutexmutex FALSE SendMutex While 1 mutex Lock a a 2 mutex Unlock 使用信号量对象实现线程同步 CSemaphore publicCSyncObject CSemaphore LONGlInitialCount 1 LONGlMaxCount 1 LPCTSTRpstrName NULL LPSECURITY ATTRIBUTESlpsaAttributes NULL lInitialCount是信号量的初始值 默认为1 相当于互斥量CMutex 表示资源的数目 lMaxCount是信号量的最大值 为资源的最大数目 pstrName是信号量的名称 lpsaAttributes是该信号量的安全属性 一般为NULL 使用事件对象实现线程同步 classCEvent public CEvent BOOLbInitiallyOwn FALSE BOOLbManualReset FALSE LPCTSTRlpszName NULL LPSECURITY ATTRIBUTESlpsaAttribute NULL BOOLSetEvent BOOLPulseEvent BOOLResetEvent virtualBOOLUnlock 其中CEvent构造函数中bInitiallyOwn表示初始化时的状态 默认是非激发状态 bManualReset说明时间是否手动 lpszName不为空时 改事件对象就可以跨进程使用 DWORDWaitForSingleObject HANDLEhHandle 等待事件句柄DWORDdwMilliseconds 等待的最长时间 hHandle事件句柄代表事件 互斥量 信号量 线程和进程 事件对象存在两种类型 手动类型和自动类型 手动类型是由手工调用SetEvent 和ResetEvent 函数对事件设置或释放状态 自动状态是由事件自动由信号态返回到非信号态 PulseEvent 选择一个等待自动类型事件的线程或进程运行 并使事件自动由信号态返回到非信号态 使用消息实现线程之间的通信 LRESULTSendMessage HWNDhWnd 目标窗口句柄UINTMsg 消息WPARAMwParam 第一个消息参数LPARAMlParam 第二个消息参数 SendMessage函数把消息直接发送给线程的消息队列 并等待消息处理函数的处理 当消息处理函数完成处理后 调用返回 BOOLPostMessage HWNDhWnd 目标窗口句柄UINTMsg 消息WPARAMwParam 第一个消息参数LPARAMlParam 第二个消息参数 PostMessage函数也是把消息直接发送到消息队列 它并不等待消息处理函数处理就直接返回 SendMessage和PostMessage主要区别就是

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论