chap6-多线程编程技术_第1页
chap6-多线程编程技术_第2页
chap6-多线程编程技术_第3页
chap6-多线程编程技术_第4页
chap6-多线程编程技术_第5页
已阅读5页,还剩52页未读 继续免费阅读

下载本文档

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

文档简介

计算机控制工程计算机控制工程第六章多线程编程技术线程间通信3多线程概述1线程的操作2

线程同步4实例-多线程实现计算机间通信5小结6计算机控制工程Windows是一种多任务的操作系统。Windows中一个进程包含一个或多个线程。第六章多线程编程Windows多线程编程方式:1、Win32API;2、标准C库;3、MFC类库;目的:提高程序执行效率;提高用户体验;计算机控制工程第一节多线程概述多线程概念一多线程指在同一程序中同时执行多个任务或多个程序。这意味着用户可以将整个任务分成几个线程,然后让操作系统同时执行。注意:虽然在微观上仍然是分时的,但这种调度策略确实能够提高CPU的利用率,从而提高程序的执行效率。关键是理解线程与进程的概念。计算机控制工程第一节多线程概述Aprocesswithtwothreadsofexecution

onasingleprocessor.计算机控制工程第一节多线程概述1.进程进程是一个程序实例;进程占据4GB地址空间,在该空间存放应用程序

执行所需要的各种资源;

Win32进程没有活力,是静态的。

2.线程线程是CPU调度计算任务的最小单位;

Win32进程创建时,会自动创建一个主线程;主线程可以创建其它线程(辅助线程)计算机控制工程第一节多线程概述第一节多线程概述应用场合二总体上来讲,进程占用资源比线程多得多。实际上线程只有一个内核对象和一个堆栈。开发人员应设法增加线程在解决编程问题。避免创建新的线程。场合一:耗时操作可单独为其开辟一个线程,因为在主线程中执行这些操作会让用户体验差。场合二:针对用户界面。线程可分为用户接口线程和工作者线程。用户接口线程不应该执行时长100ms以上的工作;工作者线程不应该处理用户界面。工作线程不具备消息循环计算机控制工程第二节线程的操作创建线程一线程创建步骤:编写线程函数(无特殊要求);创建线程。1.AfxBeginThread()函数(MFC)

MFC支持两种线程类型:工作者线程和用户接口线程计算机控制工程第二节线程的操作工作者线程:CWinThread*AfxBeginThread( AFX_THREADPROCpfnThreadProc, LPVOIDpParam, intnPriority=THREAD_PRIORITY_NORMAL, UINTnStackSize=0, DWORDdwCreateFlags=0, LPSECURITY_ATTRIBUTESlpSecurityAttrs=NULL);UINT__cdeclThreadFunction(LPVOIDpParam)

计算机控制工程第二节线程的操作用户接口线程:CWinThread*AfxBeginThread( CRuntimeClass*pThreadClass, intnPriority=THREAD_PRIORITY_NORMAL, UINTnStackSize=0, DWORDdwCreateFlags=0, LPSECURITY_ATTRIBUTESlpSecurityAttrs=NULL);TheRUNTIME_CLASSofanobjectderivedfromCWinThread.计算机控制工程第二节线程的操作2.CreateThread()函数(Win32API)计算机控制工程第二节线程的操作3._beginthreadex()函数(C运行库)__cdecl调用协议__stdcall调用协议计算机控制工程第二节线程的操作终止线程二终止线程有三种方法:线程函数自然退出;使用退出函数;使用TerminateThread()函数。1.线程函数自然退出在线程函数内部设置某种条件,当该条件满足时,就不断执行该线程函数体;当条件不满足时,就退出线程函数体。当线程函数退出时,将使系统自动清除该线程所占用资源,然后正常退出。计算机控制工程第二节线程的操作2.使用退出函数在线程运行期间必须终止线程。此时只能在线程函数体内使用退出线程的函数。使用退出函数,可以保证资源能够正确释放。AfxBeginThread() voidAfxEndThread(UINTnExitCode)CreateThread() voidExitThread(DWORDdwExitCode)_beginthread() void_endthread(void);计算机控制工程第二节线程的操作3.使用TerminateThread()函数在线程函数外部将线程终止。 BOOLTerminateThread(){ HANDLEhThread; DWORDdwExitCode; }计算机控制工程第二节线程的操作内存泄漏三合理的使用C运行库、WinAPI以及MFC创建的终止线程。计算机控制工程第三节线程间通信使用全局变量一同一进程创建的各个线程间通常需要进行数据交换。常用的数据交换方法是使用全局变量;另外,各线程之间可能要交换一些状态,可考虑使用消息。最简单的方法是使用全局变量;仅仅需要在实现文件顶部申明就可直接使用。缺点:???破坏结构化程序设计。计算机控制工程第三节线程间通信使用自定义消息二通常创建工作者线程执行某个特定的计算任务。在该线程中对于某些操作状态必须及时通知主线程,以便主线程进行一定的处理(如更新界面的参数)。显然采用全局变量不能满足要求。解决方式:考虑使用用户自定义消息,通过在消息参数中指定消息的内容,将消息邮寄到程序消息队列中。主程序一旦收到该消息后,根据消息的内容,可以及时处理线程的请求。计算机控制工程第三节线程间通信步骤:1.声明自定义消息:在头文件顶部加入消息名称声明:

constWM_THREADMSG=WM_USER+100;2.声明消息响应函数:在头文件//}}AFX_MSG和“DECLARE_MESSAGE_MAP()”之间声明消息响应函数:

Afx_msgLONGOnThreadMsg(WPARAMwParam,

LPARAM,lParam)3.建立消息连接:在实现文件//}}AFX_MSG_MAP和

“END_MESSAGE_MAP()”之间:

ON_MESSAGE(WM_THREADMSG,OnThreadMsg)计算机控制工程第三节线程间通信4.编写消息响应函数:在实现文件中,添加消息函数函数的实现体:

LONGCMyClass::OnThreadMsg(WPARAMwParam, LPARAMlParam){ //加入响应函数的具体处理代码 }5.寄送自定义消息:BOOLPostMessage(HWNDhWnd,UINTMsg,

WPARAMwParam,LPARAMlParam);计算机控制工程第四节线程同步多线程引入了新问题:线程之间经常需要同时访问一些资源,因此共享资源进行访问引起冲突是不可避免的。解决方法:线程同步;Win32API解决方案:

临界区 (CriticalSection)

互斥对象 (Mutex)

信号量 (Semaphore)

事件 (Event)计算机控制工程第四节线程同步使用临界区一Acriticalsectionobjectprovidessynchronizationsimilartothatprovidedbyamutexobject,exceptthatacriticalsectioncanbeusedonlybythethreadsofasingleprocess.Event,mutex,andsemaphoreobjectscanalsobeusedinasingle-processapplication,butcriticalsectionobjectsprovideaslightlyfaster,moreefficientmechanismformutual-exclusionsynchronization(aprocessor-specifictestandsetinstruction).Likeamutexobject,acriticalsectionobjectcanbeownedbyonlyonethreadatatime,whichmakesitusefulforprotectingasharedresourcefromsimultaneousaccess.计算机控制工程第四节线程同步1.声明CRITICAL_SECTION对象(头文件中)

CRITICAL_SECTION cs;2.初始化CRITICAL_SECTION对象(实现文件中,如可

以在OnCreate()中初始化)

InitializeCriticalSection(&cs);3.进入临界区:在线程函数中,在访问共享资源之前加入:

EnterCriticalSection(&cs);4.离开临界区:共享资源操作完成后,调用下述函数:

LeaveCriticalSection(&cs);检查临界区是否被占用,若占用则停止在此处,直至临界区释放;若未占用,则继续执行释放临界区的占用,为其它程序访问共享资源提供机会。计算机控制工程第四节线程同步使用互斥对象二A

mutexobject

isasynchronizationobjectwhosestateissettosignaledwhenitisnotownedbyanythread,andnonsignaledwhenitisowned.Onlyonethreadatatimecanownamutexobject,whosenamecomesfromthefactthatitisusefulincoordinatingmutuallyexclusiveaccesstoasharedresource.Forexample,topreventtwothreadsfromwritingtosharedmemoryatthesametime,eachthreadwaitsforownershipofamutexobjectbeforeexecutingthecodethataccessesthememory.Afterwritingtothesharedmemory,thethreadreleasesthemutexobject.

计算机控制工程第四节线程同步1.声明互斥对象(头文件中)

HANDLE hMutex;2.建立并初始化互斥对象(如在OnCreate()中初始化)hMutex=CreateMutex(NULL,FALSE,NULL);3.等待互斥对象:线程函数中,在访问共享资源之前加入:WaitForSingleObject(hMutex,INFINITE);4.释放互斥对象:共享资源操作完成后,调用下述函数:ReleaseMutex(hMutex);检查互斥对象是否被占用,若占用则停止在此处,直至互斥对象释放;若未占用,则继续执行释放互斥对象的占用,为其它程序访问共享资源提供机会。计算机控制工程第四节线程同步使用信号量三Asemaphoreobjectisasynchronizationobjectthatmaintainsacountbetweenzeroandaspecifiedmaximumvalue.Thecountisdecrementedeachtimeathreadcompletesawaitforthesemaphoreobjectandincrementedeachtimeathreadreleasesthesemaphore.Whenthecountreacheszero,nomorethreadscansuccessfullywaitforthesemaphoreobjectstatetobecomesignaled.Thestateofasemaphoreissettosignaledwhenitscountisgreaterthanzero,andnonsignaledwhenitscountiszero.计算机控制工程第四节线程同步1.声明信号量对象(头文件中)

HANDLE hSemaphore;2.建立并初始化信号量(如在OnCreate()中初始化)hMutex=CreateSemaphore(NULL,3,5,NULL);3.等待互信号量:线程函数中,在访问共享资源之前加入:WaitForSingleObject(hSemaphore,INFINITE);4.释放信号量:共享资源操作完成后,调用下述函数:ReleaseSemaphore(hSemaphore,1,NULL);检查信号量计数是否大于0.若不大于0,则程序停在此处,直至计数值大于0;若大于0则将计数值减1,然后继续执行增加信号量计数值,为其它程序访问共享资源提供机会。计算机控制工程第四节线程同步使用事件四AneventobjectisasynchronizationobjectwhosestatecanbeexplicitlysettosignaledbyuseoftheSetEventfunction.Theeventobjectisusefulinsendingasignaltoathreadindicatingthataparticulareventhasoccurred.Forexample,inoverlappedinputandoutput,thesystemsetsaspecifiedeventobjecttothesignaledstatewhentheoverlappedoperationhasbeencompleted.Asinglethreadcanspecifydifferenteventobjectsinseveralsimultaneousoverlappedoperations,thenuseoneofthemultiple-objectwaitfunctionstowaitforthestateofanyoneoftheeventobjectstobesignaled.计算机控制工程第四节线程同步1.声明事件对象(头文件中)

HANDLE hEvent;2.建立并初始化事件(如在OnCreate()中初始化)hEvent=CreateEvent(NULL,FALSE,TRUE,NULL);3.等待事件对象:线程函数中,在访问共享资源之前加入:WaitForSingleObject(hEvent,INFINITE);4.设置事件为有信号状态:共享资源操作完成后,调用下述函数:SetEvent(hEvent);检查事件对象是否有信号。若无信号则程序停在此处,直至有信号;若有信号,则继续执行。第2参数:自动复位;第3参数:初始化为有信号状态计算机控制工程第四节线程同步各种方法比较五一个简单的规则:如果某个操作必须等待另一个操作完成,则考虑使用事件对象;同一时刻,同一个应用程序指定个数线程要访问同一资源,则使用信号量;同时访问同一个资源的应用程序多于1个,应该使用互斥对象;否则使用临界区。计算机控制工程第五节多线程两台计算机串口通信程序以串口程序设计为例说明:使用WinAPI编写串口程序时,为实现事件驱动方式,可以考虑单独建立一个线程,在该线程中循环检测串口事件,当串口发生感兴趣事件时,就发送消息,通知其它线程到串口读取数据。当使用多个串口时,使用多线程为每个串口开辟一个线程,处理各个串口的数据接收。当有接受数据时,通过某种方式传输给主线程进行显示和处理。计算机控制工程多线程应用框架一以两台计算机间通信的程序为例多线程编程的具体方法。…….ON_MESSAGE(WM_MYMSG,OnReceiveEvent)………….hThreadEvent=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadProcEvent,&dwParam,0,&dwThreadID);……DWORDThreadProEvent(LPVOIDpParam){//…//满足某种条件时;::PostMessage(hWnd, WM_MYMSG, 0, (LPARAM)EV_RXCHAR);…….}LONGCPC2PCView::OnReceiveEvent(…){ …… //读取串口操作 ……}第五节多线程两台计算机串口通信程序计算机控制工程两台计算机之间通信方式二第五节多线程两台计算机串口通信程序1.通过网线传输2.通过USB线传输3.通过并口传输(SPP、ECP)4.通过串口传输(2RxD、3TxD号线对调)计算机控制工程第五节多线程两台计算机串口通信程序通信协议三1.通信流程通信采用发送/应答半双工方式。通信过程分为:发送请求和发送文件两个过程。发送请求:发送方首先发出请求包,并等待应答方响应。若收到应答方ACK(6)响应,发送数据包;若收到应答方NAK(21)响应,重发请求包;若收到应答方CAN(24)响应,取消本次发送请求;计算机控制工程第五节多线程两台计算机串口通信程序发送文件:发送方将待发送的文件以1024字节为单位拆分成N个数据片段,最后一个数据片段长度不定。每次使用普通数据包发送一个数据片段,若接受方接受正确,会发送一个ACK响应,发送方在收到正确的响应后,继续发送含有下一个数据片段的普通数据包;若发送方收到NAK响应,则重发上一次发送的普通数据包。这个发送过程需要循环N-1次。当发送方发送到第N个数据片段时,使用结束包格式进行发送,若接受方正确响应ACK,则通信正常结束;若接受方响应NAK,则发送方重发含有第N个数据片段的接受包计算机控制工程第五节多线程两台计算机串口通信程序重要说明:发送方对于同一个数据包的重发操作,设定最多进行3次。3次后,发送方若仍接受不到ACK响应,则中断文件传输操作,并提示通信错误。思考:

如用4个字节表示文件长度;则文件最大长度是多少?给定合法长度文件,如何填装4个字节;计算机控制工程第五节多线程两台计算机串口通信程序数据包格式四1.请求包长度由文件名长度决定从ENG开始到其前面所有字节的异或运算和2.普通数据包计算机控制工程3.结束包第五节多线程两台计算机串口通信程序4.响应包:长度固定为1个字节。计算机控制工程第五节多线程两台计算机串口通信程序通信实现思路五通信程序使用WindowsAPI事件驱动方式、多线程技术。在程序中,为通信的事件检测设立一个单独的事件线程,该线程负责监视串口事件。当串口收到字符或发生读超时时,该线程便发送相应消息。通信消息响应函数捕获事件线程发送的消息,并根据消息类型进行处理。所有消息公用一个消息响应函数,故设置3个反映当前通信状态的变量,进入消息响应函数后,通过对这些通信状态变量值的不同采取不同的操作。计算机控制工程第五节多线程两台计算机串口通信程序1.功能描述双机通信程序。既可作为发送方使,也可作为接受方使用。程序运行后,自动进入接受态。2.事件线程函数

为处理通信事件,专门建立一个事件线程。在该事件线程函数中,监视串口事件的当前消息,包括是否收到新字符和是否发送超时。当收到新字符或发生超时,便发送Windows消息。计算机控制工程第五节多线程两台计算机串口通信程序事件线程函数处理流程图计算机控制工程3.消息响应函数第五节多线程两台计算机串口通信程序既可作为发送又可作为接受程序:1:发送状态;10:接受状态0态:表示发送操作尚未开始,程序处于接受状态。程序初次启动或完成一次传送后处于该状态。1态:表示发送操作已经开始,请求包已经发出,等待接受方响应。若接受方响应NAK,则重发请求包;若接受方响应ACK,则发送方判断文件长度,若文件长度大于1024字节,则发送第一个普通数据包,然后将发送操作置为2态,否则发送结束数据包,然后将发送状态置为3态。2态:表示发送操作已经开始,并且第一个普通包已经发出,等待接受方响应。若响应NAK:重发;状态不变若响应CAN:取消;若响应ACK:计算剩余部分长度,如大于1024字节,则继续发送普通数据包,状态不变,否则发送结束数

温馨提示

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

评论

0/150

提交评论