串口通讯vc多线程编程_第1页
串口通讯vc多线程编程_第2页
串口通讯vc多线程编程_第3页
串口通讯vc多线程编程_第4页
串口通讯vc多线程编程_第5页
免费预览已结束,剩余21页可下载查看

下载本文档

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

文档简介

1、VC VC 多线程编程多线程编程多线程编程多线程编程(转转转转VC 中多线程使用比较广泛且实用,IDD_SINGLETHREAD_DIALOG Sleep(6000);6 进VC VC 多线程编程多线程编程多线程编程多线程编程(转转转转VC 中多线程使用比较广泛且实用,IDD_SINGLETHREAD_DIALOG Sleep(6000);6 进main ain Windows CPUCPU 时间,操作系统以轮换方式向线程提供时间片,这就给人一种假象,好象这些线程都在同时运行。由此可见,如果两个非常活跃的线程为了抢夺对 CPU Win32 SDK 理中的各种同步、互斥和临界区等操作。Visua

2、l C+ 6.0 MFC 三Win32API Win32 API 1、HANDLEDWORD dwStackSize,LPVOID lpParameter,LPDWORD lpThreadId);lpThreadAttributesSECURITY_ATTRIBUTES 结构的指针,该结构决定了线程的安全属性,一般置为 NULL;为(LPTHREAD_START_ROUTINE)ThreadFunc,ThreadFunc 是线程函数名; ResumeThread 被调用;lpThreadAttributesSECURITY_ATTRIBUTES 结构的指针,该结构决定了线程的安全属性,一般置为

3、 NULL;为(LPTHREAD_START_ROUTINE)ThreadFunc,ThreadFunc 是线程函数名; ResumeThread 被调用;NULL2、DWORD SuspendThread(HANDLE hThread); 该函数用于挂起指定的线程,如果函数执行3、DWORDResumeThread(HANDLEhThread); 4、VOID ExitThread(DWORD dwExitCode); 该函数用于线程终结自身的执行,主要dwExitCode 用来设置线程的退出码。 6、DWORDU四、Win32API多线程编程例程1 MultiThread1在 IDIDC_

4、START,IDC_STOP IDC_STOPDisabledID IDC_TIME Read-MultiThread1Dlg.h文件中添加线程函数CMultiThread1Dlg 的外部。voidThreadFunc(); protectedHANDLEDWORD ThreadID; ID。protectedHANDLEDWORD ThreadID; ID。MultiThread1Dlg.cppm_bRun volatiOOL m_bRun; m_bRun m_bRun volatile 修饰符的,volatile 的全局变量来说,volatile 是一个非常重要的修饰符。voidCTime

5、CStringstrTime; m_bRun TRUE void/TODO:Addyourcontrolnotificationhandlercodehere IDC_STOPvoid/TODO:Addyourcontrolnotificationhandlercodehere Win32API 2 在 ID IDC_START MultiThread2Dlg.h:void CMultiThread2Dlg在类添加protected型变量HANDLE2 在 ID IDC_START MultiThread2Dlg.h:void CMultiThread2Dlg在类添加protected型变量H

6、ANDLEDWORDThreadID; ClassWizardIDC_COUNT添加MultiThread2Dlg.cpp 文件中添加:void void DWORD NDLEhHandle,DWORDhHandle为要监视的对象(一般为同步对象,也可以是线程)dwMilliseconds hHandle 函数时, 线程暂时挂起, 系统监视 hHandle 所指向的对象的状态。如果在挂起的 dwMilliseconds毫秒内,线程所等待的对象变为有信号状态,则该函数立即返回;如果超时照样返回。dwMilliseconds有两个具有特殊意义的值:0INFINITE0,则该函 IDC_START

7、例程3 IDC_START 例程3 typedeflongsecondArgu, threadFunc 3MultiThread3将演示如何传送一个指向结构体的指针参数。 建立一个基于MultiThread3,在 IDC_STARTIDC_PROGRESS1; IDC_PROGRESS1CProgressCtrlMultiThread3Dlg.hstructU : ThreadFunc(LPVOID lpParam); protected型变量: HANDLE hThread; DWORD ThreadID; MultiThread3Dlg.cpp文件中进行如下操作:定义公共变量 thread

8、Info Info;void CMultiThread3Dlg:OnStart()/TODO:Addyourcontrolnotificationhandlercode /TODO:Addextrainitializationhere /TODO:Addextrainitializationhere return TRUE;/returnunlessyousetthefocustoaU threadInfo*returnvoid 函数中添加/* */你就会发现进度条不进行刷新, 主线程也停止了反应。什么原因呢? 这是因为 WaitForSingleObject 函数等待子线程(ThreadFu

9、nc ) 结束时, 导致了线程死锁。因为 WaitForSingleObject 函数会将主线程挂起(任何消息都得不到处理ThreadFunc4 该例程测试在 Windows 下最多可创建线程的数目。建立一个基于框的工程IDD_MULTITHREAD4_DIALOGIDC_TEST IDC_COUNTRead-onlyOOL DWORDWINAPIthreadFunc(LPVOIDreturn m_bRunFlag TRUEIDC_TEST,添加其响应消息voidDWORDDWORDWINAPIthreadFunc(LPVOIDreturn m_bRunFlag TRUEIDC_TEST,添加

10、其响应消息voidDWORDlong nCount=0;不断创建线程, 直到再不能创建为止的 线 程 结 束/ 延 时秒 , 等 待 所 有 创 建m_bRunFlag=TRUE; 程。二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列消息循环工作者线程没有消息机制,通常用来执计算任务,如冗长的计算过程,打Win32的API在MFC中,一般用全局函数hread()来创建并初始化一个线程的运行,该函数有(1)hread*Uroc:指向工作者线程的执行函数的指针,线程函数原型必须 ExecutingFunction(LPVOID pParam); 请注意,ExecutingF

11、unction()U0 表明执行成功。如下: nPriority:线程(1)hread*Uroc:指向工作者线程的执行函数的指针,线程函数原型必须 ExecutingFunction(LPVOID pParam); 请注意,ExecutingFunction()U0 表明执行成功。如下: nPriority:线程的优先级。如果为 0,则线程与其父线程具有相同的优先级 (2)hread*CRuntimeClass*Uhread pThreadClass hread m_nThreadID:ID;对BOOL DWORDU 应参数有相同含义,该函数执行成功,返回非 0 值,否则返回 0但是也可以通过

12、两步法来创建线程:首先创建 hreadvirtual BOOL InitInstance()。该函数返回线程的退出码,0 0 InitInstance()六、MFC VisualC6.0 C32位Win32MC InitInstance()。该函数返回线程的退出码,0 0 InitInstance()六、MFC VisualC6.0 C32位Win32MC+风格的应用程序,二者各有其优缺点。基于n2的应用程序执行代码小巧,运行效率高,但要求程序员编写的代码较多,且需要管理系统提供给程序的所有资MCelr uo 为程序员提供了一些工具来管理用户源程序,其缺点是类库代Visual使用 MFC 类库

13、进行程序开发知道,MFC中的线程分为两种:用户界面线用 MFC 类库编程实现工作者线程5 Win32API对照,MFC 3MultiThread3 在IDC_STARTIDC_PROGRESS1;IDC_MILLISECONDIDC_PROGRESS1CProgressCtrlm_ctrlProgress;MultiThread5Dlg.h 文件中添加一个结构的定义:structU ThreadFunc(LPVOID protectedhread*MultiThread5Dlg.cpp文件中进行如下操作:定义公共变量:threadInfovoid CMultiThread5Dlg:OnStar

14、t()/TODO:Addyourcontrolnotificationhandlercode /TODO:Addextrainitializationhere return TRUE; /TODO:Addextrainitializationhere return TRUE;/returnunlessyousetthefocustoaU threadInfo*returnMFC ClassWizardCW class CUIThread : public CWhread的派生类(CUIThread 类为例/protectedconstructorusedbydynamic/ClassWizar

15、dgeneratedvirtualfunctionvirtual BOOL/virtual/Generatedmessagemap/NOTE-theClassWizardwilladdand/virtual/Generatedmessagemap/NOTE-theClassWizardwilladdandremovememberfunctionsBOOL CUIThread:InitInstance()CFrameWnd*wnd=newwnd-Create(NULL,UIThreadWindow); returnvoidCUIThread*pThread=newCUIThread(); AUI

16、ThreadDlg.cpp #includeBUIThread.hCUIThread()WM_QUIT 资hreadInitInstance FALSEInitInstance 6 在 右击工程并选中“NewClass”为工程添加基类为hread派生线程类CUIThread为IDD_UITHREADDLGCDialog CUIThreadDlg使用 ClassWizard 为 CUIThreadDlg 类添加 WM_LBUTTONDOWN voidnFlags,为IDD_UITHREADDLGCDialog CUIThreadDlg使用 ClassWizard 为 CUIThreadDlg 类

17、添加 WM_LBUTTONDOWN voidnFlags, UIThread.h#includeCUIThreadprotected CUIThreadclassCUIThread:public/protectedconstructorusedbydynamic/ClassWizardgeneratedvirtualfunctionvirtual BOOL/AFX_VIRTUAL/CUIThreadDlgvirtual /Generatedmessagemap/NOTE-theClassWizardwilladdandremovememberfunctionsBOOL CUIThread:In

18、itInstance()returnreturnvoid CMultiThread6Dlg:OnUiThread()hreadMultiThread6Dlg.cpp#include七、线程间通一般而言应用程序中的一个次要线程总是为主线程执行特定的任务,这样,也是复杂和频繁的,下面将进行说明。 通信volatile 修符,它告诉编译器无需对该returnvoid CMultiThread6Dlg:OnUiThread()hreadMultiThread6Dlg.cpp#include七、线程间通一般而言应用程序中的一个次要线程总是为主线程执行特定的任务,这样,也是复杂和频繁的,下面将进行说明。

19、通信volatile 修符,它告诉编译器无需对该变量作任何的优化,即无需将它放到一个寄存器中,并且可被外部改变。如果线程间所需传递的信息较复杂该结构的指针进行传递信息可以定义一个结构,通过传递指可以在一个线程的执行函数中向另一个线程发送自定义的消息来到通信的目的。一个线程向另外一个线程发送消息是通过操作系统实现的。利用 7 该例程演示了如何使用自定义消息进行线程间通信CCalculateThreadCCalculateThreadWM_DISPLAY消息,主线程收在IDD_MULTITHREAD7_DIALOG 中加入三个单选按钮 标题分别为加框MultiThread7Dlg.hnAddend

20、; voidvoidvoidOnInitDialogBOOL nAddend; voidvoidvoidOnInitDialogBOOL nAddend=10; MultiThread7Dlg.h 中添加: #include CalculateThread.h #define WM_DISPLAY WM_USER+2classCMultiThread7Dlg:public/Construction CMultiThread7Dlg(CWnd*pParent=NULL);/standardconstructor CCalculateThread* m_pCalculateThread; ram,

21、LPARAMlParam); MultiThread7Dlg.cppreturn以上代码使得主线程类 CMultiThread7Dlg 可以处理 WM_DISPLAY 消息,即在US void 右击工程并选中“ New Class ” 为工程添加基类为 CW hread 派生线程类CalculateThread.h classCCalculateThread:public afx_msgLONGvoid 右击工程并选中“ New Class ” 为工程添加基类为 CW hread 派生线程类CalculateThread.h classCCalculateThread:public afx_m

22、sgLONGCalculateThread.cpp ram,LONGlParam); LONG Return /NOTE-theClassWizardwilladdandremovemacrosON_THREAD_MESSAGE(WM_CALCULATE,OnCalculate) / 和主线程对比, 注意它们的区别 #include以上代码为 类添加了 WM_CALCULATE 消息, 消息的响应函数是ram nTmpt0.5WM_DISPLAY 消息进行显示,nTmpt作为参数传递。 编译并运行该例程,八、线程的同的MFC 临界区(CCriticalSection) 事件(CEvent) 互

23、斥量(CMutex) 信号量ACCriticalSection 一个独占性共享资源时,CCriticalSection CCriticalSection类的一个全局对象(以使各个线程均能的MFC 临界区(CCriticalSection) 事件(CEvent) 互斥量(CMutex) 信号量ACCriticalSection 一个独占性共享资源时,CCriticalSection CCriticalSection类的一个全局对象(以使各个线程均能CCriticalSection critical_section;在临界区完毕后,使用 CCriticalSection 的成员函数 Unlock(

24、)临界区A critical_section.Lock();语句时,如果其它线程(B)正在执行 critical_section.Lock();critical_section. Unlock();A 就会等待,B critical_section. Unlock();A 才会继续执行。 下面再通过一个MultiThread8 在 IDIDC_WRITEWIDC_WRITED,WDIDIDC_WIDC_D,Read-only;MultiThread8Dlg.hUU ClassWizardIDC_W IDC_D CEdit m_ctrlW MultiThread8Dlg.cpp头添加:#incl

25、ude afxmt.hcritical_section; char g_Array10;ClassWizardIDC_W IDC_D CEdit m_ctrlW MultiThread8Dlg.cpp头添加:#include afxmt.hcritical_section; char g_Array10;U CEditreturn 0;U CEditreturn 0;IDC_WRITEWIDC_WRITED,添加其响应函数: void CMultiThread8Dlg:OnWritew()hread voidhread BCEvent 另外一个线程(B)CEvent类,线程ABhread BC

26、Event 另外一个线程(B)CEvent类,线程ABCEvent 类对象的状态,并在相应的时候采取相应的操作。MFC中,CEvent 类对象有两种类型:人工事件和自动事件CEvent 后会自动返回到无信号状态;而人工事件对象获得信号后可利ReSetEvent()CEvent 类的对CEvent BOOL bManualReset=FALSE,LPCTSTR bInitiallyOwn:指定事件对象初始化状态,TRUE为有信号,FALSE CEvent CEvent ResetEvent() 状态后,CEvent如果该函数执行成功,则返回非零3、BOOL CEventResetEvent();

27、 该函数将事件的状态设置为无信号状态,并保持该状态直至 一般通过调用已经介绍了该函数。由于语言描述的原因,CEvent MultiThread9 在框 IDD_MULTITHREAD9_DIALOG 中加入一个按钮和两个编辑框控件,按钮的 ID ID分别为IDC_W IDC_DRead-在 MultiThread9Dlg.h 文件中 两个线程函数: WriteW(LPVOID pParam); ClassWizardIDC_W IDC_D CEdit m_ctrlW MultiThread9Dlg.cpp文件中添加如下内容: 为了文件中能够正确使用同步类,在文件开头添加 #include af

28、xmt.h 定义事件对象和一个字符数组,CEventeventWriteD;char在 MultiThread9Dlg.h 文件中 两个线程函数: WriteW(LPVOID pParam); ClassWizardIDC_W IDC_D CEdit m_ctrlW MultiThread9Dlg.cpp文件中添加如下内容: 为了文件中能够正确使用同步类,在文件开头添加 #include afxmt.h 定义事件对象和一个字符数组,CEventeventWriteD;char添加线程函数: return 0;U CEditreturn仔细分析这两个线程函数, 您就会正确理解 类。 线程 Wri

29、teD 执行到 eventWriteDWaitForSingleObject()IDC_WRITEW,添加其响应函数:voidhread hread WC类对象与临界区对象很像.互斥对象与临界区对象的不同在于:互斥对象可以在进程间使用,而D、使类当需要一个计数器CSemaphore 已1CSemaphore WC类对象与临界区对象很像.互斥对象与临界区对象的不同在于:互斥对象可以在进程间使用,而D、使类当需要一个计数器CSemaphore 已1CSemaphore 类对象所控制的资源可以同时接受CSemaphore CSemaphore(LONGLONGLPCTSTR lMaxCount:信号

30、量对象计数值的最大值,该参数决定了同一时刻由信号量保护的源的线程最大数目后两个参数在同一在用 CSemaphore ; 线1CSemaphore 10MultiThread10 在 ABCID分别为IDC_A、IDC_B CSemaphore 10MultiThread10 在 ABCID分别为IDC_A、IDC_B IDC_CRead-MultiThread10Dlg.hU 使用ClassWizard分别给IDC_AIDC_B和IDC_C添加CEdit类变量m_ctrlAm_ctrlB和m_ctrlC;MultiThread10Dlg.cpp 文件中添加如下内容:#includeafxmt.h 定义信号量对象和一个字符数组,为了能够在不同线定义为全局变量:CSemaphoresemaphoreWrite(2,2);资源最多2 个char2 U CEditCString str;return 0;U CEditCString str;return 0;U CEditreturn 0;

温馨提示

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

评论

0/150

提交评论