《vc多线程》PPT课件.ppt

上传人:za****8 文档编号:16088115 上传时间:2020-09-18 格式:PPT 页数:41 大小:120.02KB
返回 下载 相关 举报
《vc多线程》PPT课件.ppt_第1页
第1页 / 共41页
《vc多线程》PPT课件.ppt_第2页
第2页 / 共41页
《vc多线程》PPT课件.ppt_第3页
第3页 / 共41页
点击查看更多>>
资源描述
第9章 多线程,内容摘要: 创建线程 实现线程间通信 利用线程同步技术保障数据安全,返回目录,9.1 创建线程,学习目标 调用AfxBeginThread()来启动线程。,9.1,返回第9章,程序的实现步骤,利用AppWizard生成程序框架(ThreadTest ) 编辑资源 添加菜单响应函数 编写线程函数 在视中输出信息,9.1,步骤1 生成程序框架(MenuTest),项目名称: ThreadTest 选择单文档界面应用程序(Single document),9.1,步骤2 编辑资源,1.编辑菜单资源 线程 Pop-up 选中 Caption ID 启动线程 ID_THREAD_START 其他任务 ID_TREEAD_OTHER 2.编辑对话框资源,9.1,IDD_DIALOG_THRAED,CDlgThread,步骤3 添加菜单响应函数,Class Name Objects IDs Messages CThreadTestView ID_THREAD_START COMMAND CThreadTestView ID_TREEAD_OTHER COMMAND,9.1,void CThreadTestView:OnThreadStart() HWND hWnd = GetSafeHwnd(); AfxBeginThread(TreadProc, hWnd, THREAD_PRIORITY_NORMAL); ,void CThreadTestView:OnThraedOther() CDlgThread dlg; dlg.DoModal(); ,步骤4 编写线程函数,1. 在视类中添加两个成员变量。并在构造函数中初始化,9.1,class CThreadTestView : public CView public: CString m_strMessage; int m_iTime; ,CThreadTestView:CThreadTestView() m_strMessage = 没有线程启动; m_iTime = 0; ,步骤5 在视中输出信息,9.1,void CThreadTestView:OnDraw(CDC* pDC) CThreadTestDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); / TODO: add draw code for native data here char chNumber6; itoa(m_iTime, chNumber, 10); pDC-TextOut(30,30, m_strMessage); pDC-TextOut(30,50,chNumber); ,2. 线程函数,9.1,UINT TreadProc(LPVOID param) CThreadTestApp *pApp=(CThreadTestApp *) AfxGetApp(); CMainFrame *pMainFrame = (CMainFrame *)pApp-GetMainWnd(); CThreadTestView *pView = (CThreadTestView *) pMainFrame-GetActiveView(); pView-m_strMessage = 启动了一个线程!; while(pView-m_iTime m_iTime +; pView-Invalidate(); pView-m_iTime =0; pView-m_strMessage = 线程结束!; return 0; ,基本知识,CWnd类的GetSafeHwnd();返回窗口句柄 AfxBeginThread(); 线程函数 ( 返回UINT) CMainFrame:GetActiveView(); :Sleep(1000);,9.1,9.2 线程间通信,学习目标 1. 使用全局变量实现线程间通信 2.使用消息实现线程间通信 3.使用CEvent类实现线程间通信,9.2,返回第9章,1. 使用全局变量实现线程间通信,在上一节程序的基础上,进行以下操作: (1)在“线程”菜单中添加菜单项: “终止线程”,ID_THREAD_STOP。 (2)在ThreadTestView.cpp文件中添加一个全局变量threadController,用来控制线程是否继续。添加方法是在ThreadTestView.cpp的最上面,在endif下面添加下面的语句: volatile int threadController; (3)在视类中为“停止线程”添加消息处理函数OnThreadStop ()。,9.2,void CThreadTestView:OnThreadStop() threadController = 0; ,1. 使用全局变量实现线程间通信,4修改OnThreadStart ()函数,代码如下所示:,9.2,void CThreadView:OnStartthread() threadController = 1; HWND hWnd = GetSafeHwnd(); AfxBeginThread(TreadProc, hWnd, THREAD_PRIORITY_NORMAL); ,5修改ThreadProc()函数的代码,代码如下:,9.2,UINT TreadProc(LPVOID param) CThreadTestApp *pApp=(CThreadTestApp *) AfxGetApp(); CMainFrame *pMainFrame = (CMainFrame *)pApp-GetMainWnd(); CThreadTestView *pView = (CThreadTestView *) pMainFrame-GetActiveView(); pView-m_strMessage = 启动了一个线程!; while(threadController) :Sleep(1000); pView-m_iTime +; pView-Invalidate(); pView-m_iTime =0; pView-m_strMessage = 线程结束!; return 0; ,2.使用消息实现线程间通信,(1)在ThreadTestView.h文件中定义消息: const WM_THREAD_SENDMESS = WM_USER + 20; (2)在ThreadTestView.h文件中添加消息函数声明: afx_msg int OnThreadSendmess(); (3)在ThreadTestView.cpp文件中添加消息映射: ON_MESSAGE(WM_THREAD_SENDMESS, OnThreadSendmess) (4)OnThreadSendmess()代码如下:,9.2,int CThreadTestView:OnThreadSendmess() m_iTime +; Invalidate(); return 0; ,2.使用消息实现线程间通信,(5)修改ThreadProc()函数如下 :,9.2,UINT TreadProc(LPVOID param) CThreadTestApp *pApp=(CThreadTestApp *) AfxGetApp(); CMainFrame *pMainFrame = (CMainFrame *)pApp-GetMainWnd(); CThreadTestView *pView = (CThreadTestView *) pMainFrame-GetActiveView(); pView-m_strMessage = 启动了一个线程!; while(threadController) :Sleep(1000); :PostMessage(HWND)param, WM_THREAD_SENDMESS, 0, 0); pView-m_iTime =0; pView-m_strMessage = 线程结束!; return 0; ,基本知识,PostMessage(HWND)param, WM_THREAD_SENDMESS, 0, 0);,4.5,3.使用CEvent类实现线程间通信,(1)Event对象:有两种状态:通信状态和非通信状态 (2)创建一个CEvent类的对象很:CEvent threadStart; 他自动的处在未通信状态 (3)threadStart.SetEvent(); 使其处于通信状态 (4)调用WaitForSingleObject()来监视CEvent对象的: :WaitForSingleObject(threadStart.m_hObject, INFINITE);,9.2,3.使用CEvent类实现线程间通信,在上一节程序的基础上,进行以下操作: (1)在ThreadTestView.cpp中:#include afxmt.h (2)在ThreadTestView.cpp中加上下列两个全局变量: CEvent threadStart; CEvent threadEnd; (3)修改ThreadProc()函数 (4)修改OnThreadStart ()函数中的内容。 (5)修改OnThreadStop ()函数中的内容。 (6)CThreadTestView添加WM_CREATE消息处理函数OnCreate()。,9.2,void CThreadTestView:OnThreadStart() threadStart.SetEvent(); ,void CThreadTestView:OnThreadStop() threadEnd.SetEvent(); ,3.使用CEvent类实现线程间通信,9.2,UINT TreadProc(LPVOID param) CThreadTestApp *pApp=(CThreadTestApp *) AfxGetApp(); CMainFrame *pMainFrame = (CMainFrame *)pApp-GetMainWnd(); CThreadTestView *pView = (CThreadTestView *) pMainFrame-GetActiveView(); :WaitForSingleObject(threadStart.m_hObject, INFINITE); pView-m_strMessage = 启动了一个线程!; BOOL keepRunning = TRUE; while (keepRunning) :Sleep(1000); int result = :WaitForSingleObject(threadEnd.m_hObject, 0); if (result = WAIT_OBJECT_0) keepRunning = FALSE; :PostMessage(HWND)param, WM_THREAD_SENDMESS, 0, 0); pView-m_iTime =0; pView-m_strMessage = 线程结束!; return 0; ,3.使用CEvent类实现线程间通信,9.2,int CThreadTestView:OnCreate(LPCREATESTRUCT lpCreateStruct) if (CView:OnCreate(lpCreateStruct) = -1) return -1; / TODO: Add your specialized creation code here HWND hWnd = GetSafeHwnd(); AfxBeginThread(TreadProc, hWnd, THREAD_PRIORITY_NORMAL); return 0; ,9.3 线程同步,学习目标 1. 使用Critical Section实现线程同步 2. 使用互斥对象(mutex)实现线程同步 3. 使用信号量(semaphore实现线程同步,9.3,返回第9章,9.3.1 使用Critical Section,1. CCriticalSection criticalSection; 2. criticalSection.Lock(); /访问前 3. criticalSection.Unlock(); /访问后,9.3,9.3.1 使用Critical Section,一个使用Critical Section 的线程安全类。,9.3,#include afxmt.h class CIntArray private: int array10; CCriticalSection criticalSection; public: CIntArray(); CIntArray() ; void SetArray(int value); void GetArray(int dstArray10); ;,9.3.1 使用Critical Section,一个使用Critical Section 的线程安全类。,9.3,#include stdafx.h #include IntArray.h CIntArray:CIntArray() CIntArray:CIntArray() ,void CIntArray:SetArray(int value) criticalSection.Lock(); for (int x=0; x10; +x) arrayx = value; criticalSection.Unlock(); void CIntArray:GetArray(int dstArray10) criticalSection.Lock(); for (int x=0; x10; +x) dstArrayx = arrayx; criticalSection.Unlock(); ,9.3.1 使用Critical Section,一个使用CIntArray的例子。,9.3,(1)使用应用向导创建一个单文档应用程序(ThreadTest )。 (2)将CIntArray类的头文件和实现文件中添加到项目中。 (3)编辑菜单资源 “线程”菜单 ID_THREAD_START:“启动线程”。 (4)在视类中添加该菜单项的响应函数 OnThreadStart()。,9.3.1 使用Critical Section,9.3,(5)在ThreadTestView.cpp文件中,加入下面6行语句。 #include MainFrm.h #include afxmt.h #include IntArray.h CIntArray intArray; int iArray110; nt intSetNumber; (6)添加下面两个全程函数。 UINT WriteThreadProc(LPVOID param) UINT ReadThreadProc(LPVOID param) (7)在OnDraw()中添加代码,9.3.1 使用Critical Section,9.3,UINT WriteThreadProc(LPVOID param) CThreadTestApp *pApp=(CThreadTestApp *) AfxGetApp(); CMainFrame *pMainFrame = (CMainFrame *)pApp-GetMainWnd(); CThreadTestView *pView = (CThreadTestView *) pMainFrame-GetActiveView(); for(int i=1; iInvalidate(); :Sleep(2000); return 0; ,9.3.1 使用Critical Section,9.3,UINT ReadThreadProc(LPVOID param) CThreadTestApp *pApp=(CThreadTestApp *) AfxGetApp(); CMainFrame *pMainFrame = (CMainFrame *)pApp-GetMainWnd(); CThreadTestView *pView = (CThreadTestView *) pMainFrame-GetActiveView(); while(1) intArray.GetArray(iArray1); pView-Invalidate(); return 0; ,9.3.1 使用Critical Section,9.3,void CThreadView:OnStartthread() / TODO: Add your command handler code here HWND hWnd = GetSafeHwnd(); AfxBeginThread(WriteThreadProc, hWnd); AfxBeginThread(ReadThreadProc, hWnd); ,9.3.1 使用Critical Section,9.3,void CThreadTestView:OnDraw(CDC* pDC) char str70; strcpy(str,线程 1 为数组设置的值是: ); int len = strlen(str); wsprintf( ,9.3.2 使用使用Mutex(互斥对象),将上例中的critical section替换成Mutex,9.3,#include afxmt.h class CIntArray private: int array10; CMutex mutex; public: CIntArray (); CIntArray (); void SetArray(int value); void GetArray(int dstArray10); ;,9.3.2 使用使用Mutex(互斥对象),9.3,#include stdafx.h #include CIntArray.h CIntArray:CIntArray() CIntArray:CIntArray() ,void CIntArray:SetArray(int value) CSingleLock singleLock( ,9.3.3 使用信号量(Semaphore),(1)创建信号量 CSemaphore Semaphore(2, 2); (2)创建一个CSingleLock对象 CSingleLock singleLock(semaphore); (3)减小信号量计数器 singleLock.Lock(); (4)增加信号量计数器 singleLock.Unlock ();,9.3,使用信号量的一个例子,1. 修改CIntArray类,9.3,#include afxmt.h class CIntArray private: int array10; CMutex mutex; CSemaphore *semaphore; public: CIntArray (); CIntArray (); void SetArray(int value); void GetArray(int dstArray10); ;,使用信号量的一个例子,1. 修改CIntArray类,9.3,CIntArray:CIntArray() semaphore = new CSemaphore(2, 2); CIntArray:CIntArray() delete semaphore; ,void CIntArray:SetArray(int value) CSingleLock singleLock( ,使用信号量的一个例子,2修改CthreadTestView.cpp文件的开始部分,9.3,#include MainFrm.h #include afxmt.h #include IntArray.h CIntArray intArray; int iArray110; int iArray210; int iArray310; int iArray410; int iArray510; int iArray610; int iArray710; int intSetNumber;,使用信号量的一个例子,3改写视类中的OnThreadStart()函数,9.3,void CThreadTestView:OnThreadStart() / TODO: Add your command handler code here HWND hWnd = GetSafeHwnd(); AfxBeginThread(WriteThreadProc, hWnd); AfxBeginThread(ReadThreadProc1, hWnd); AfxBeginThread(ReadThreadProc2, hWnd); AfxBeginThread(ReadThreadProc3, hWnd); AfxBeginThread(ReadThreadProc4, hWnd); AfxBeginThread(ReadThreadProc5, hWnd); AfxBeginThread(ReadThreadProc6, hWnd); AfxBeginThread(ReadThreadProc7, hWnd); ,使用信号量的一个例子,4添加另外6个线程函数,9.3,UINT ReadThreadProc2(LPVOID param) CThreadTestApp *pApp=(CThreadTestApp *) AfxGetApp(); CMainFrame *pMainFrame = (CMainFrame *)pApp-GetMainWnd(); CThreadTestView *pView = (CThreadTestView *) pMainFrame-GetActiveView(); while(1) intArray.GetArray(iArray2); pView-Invalidate(); return 0; ,使用信号量的一个例子,9.3,UINT ReadThreadProc3(LPVOID param) CThreadTestApp *pApp=(CThreadTestApp *) AfxGetApp(); CMainFrame *pMainFrame = (CMainFrame *)pApp-GetMainWnd(); CThreadTestView *pView = (CThreadTestView *) pMainFrame-GetActiveView(); while(1) intArray.GetArray(iArray3); pView-Invalidate(); return 0; . .,5改写视类的OnDraw()函数,使用信号量的一个例子,9.3,void CThreadTestView:OnDraw(CDC* pDC) CThreadTestDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); / TODO: add draw code for native data here char str70; strcpy(str,写线程为数组设置的值是: ); int len = strlen(str); wsprintf( ,返回第9章,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


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

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


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