线程的编程实现(操作系统.ppt_第1页
线程的编程实现(操作系统.ppt_第2页
线程的编程实现(操作系统.ppt_第3页
线程的编程实现(操作系统.ppt_第4页
线程的编程实现(操作系统.ppt_第5页
已阅读5页,还剩37页未读 继续免费阅读

下载本文档

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

文档简介

第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); A

温馨提示

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

评论

0/150

提交评论