Chinaunix首页 | 论坛 | 博客
  • 博客访问: 16498863
  • 博文数量: 5645
  • 博客积分: 9880
  • 博客等级: 中将
  • 技术积分: 68081
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-28 13:35
文章分类

全部博文(5645)

文章存档

2008年(5645)

我的朋友

分类:

2008-04-28 21:00:53

下载本文示例代码
  1、创建和终止线程  在MFC程序中创建一个线程,宜调用AfxBeginThread函数。该函数因参数不同而具有两种重载版本,分别对应工作者线程和用户接口(UI)线程。  工作者线程 CWinThread *AfxBeginThread( AFX_THREADPROC pfnThreadProc, //控制函数 LPVOID pParam, //传递给控制函数的参数 int nPriority = THREAD_PRIORITY_NORMAL, //线程的优先级 UINT nStackSize = 0, //线程的堆栈大小 DWORD dwCreateFlags = 0, //线程的创建标志 LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL //线程的安全属性);  工作者线程编程较为简单,只需编写线程控制函数和启动线程即可。下面的代码给出了定义一个控制函数和启动它的过程: //线程控制函数UINT MfcThreadProc(LPVOID lpParam){ CExampleClass *lpObject = (CExampleClass*)lpParam; if (lpObject == NULL || !lpObject->IsKindof(RUNTIME_CLASS(CExampleClass)))  return - 1; //输入参数非法  //线程成功启动 while (1) {  ...// } return 0;}//在MFC程序中启动线程AfxBeginThread(MfcThreadProc, lpObject);  UI线程  创建用户界面线程时,必须首先从CWinThread 派生类,并使用 DECLARE_DYNCREATE 和 IMPLEMENT_DYNCREATE 宏声明此类。  下面给出了CWinThread类的原型(添加了关于其重要函数功能和是否需要被继承类重载的注释): class CWinThread : public CCmdTarget{ DECLARE_DYNAMIC(CWinThread) public:  // Constructors  CWinThread();  BOOL CreateThread(DWORD dwCreateFlags = 0, UINT nStackSize = 0,LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);  // Attributes  CWnd* m_pMainWnd; // main window (usually same AfxGetApp()->m_pMainWnd)  CWnd* m_pActiveWnd; // active main window (may not be m_pMainWnd)  BOOL m_bAutoDelete; // enables 'delete this' after thread termination  // only valid while running  HANDLE m_hThread; // this thread's HANDLE  operator HANDLE() const;  DWORD m_nThreadID; // this thread's ID  int GetThreadPriority();  BOOL SetThreadPriority(int nPriority);  // Operations  DWORD SuspendThread();  DWORD ResumeThread();  BOOL PostThreadMessage(UINT message, WPARAM wParam, LPARAM lParam);  // Overridables  //执行线程实例初始化,必须重写  virtual BOOL InitInstance();  // running and idle processing  //控制线程的函数,包含消息泵,一般不重写  virtual int Run();  //消息调度到TranslateMessage和DispatchMessage之前对其进行筛选,  //通常不重写  virtual BOOL PreTranslateMessage(MSG* pMsg);  virtual BOOL PumpMessage(); // low level message pump  //执行线程特定的闲置时间处理,通常不重写  virtual BOOL OnIdle(LONG lCount); // return TRUE if more idle processing  virtual BOOL IsIdleMessage(MSG* pMsg); // checks for special messages  //线程终止时执行清除,通常需要重写  virtual int ExitInstance(); // default will 'delete this'  //截获由线程的消息和命令处理程序引发的未处理异常,通常不重写  virtual LRESULT ProcessWndProcException(CException* e, const MSG* pMsg);  // Advanced: handling messages sent to message filter hook  virtual BOOL ProcessMessageFilter(int code, LPMSG lpMsg);  // Advanced: virtual access to m_pMainWnd  virtual CWnd* GetMainWnd();  // Implementation public:  virtual ~CWinThread();  #ifdef _DEBUG   virtual void AssertValid() const;   virtual void Dump(CDumpContext& dc) const;   int m_nDisablePumpCount; // Diagnostic trap to detect illegal re-entrancy  #endif  void CommonConstruct();  virtual void Delete();  // 'delete this' only if m_bAutoDelete == TRUE  // message pump for Run  MSG m_msgCur; // current message public:  // constructor used by implementation of AfxBeginThread  CWinThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam);  // valid after construction  LPVOID m_pThreadParams; // generic parameters passed to starting function  AFX_THREADPROC m_pfnThreadProc;  // set after OLE is initialized  void (AFXAPI* m_lpfnOleTermOrFreeLib)(BOOL, BOOL);  COleMessageFilter* m_pMessageFilter; protected:  CPoint m_ptCursorLast; // last mouse position  UINT m_nMsgLast; // last mouse message  BOOL DispatchThreadMessageEx(MSG* msg); // helper  void DispatchThreadMessage(MSG* msg); // obsolete};  启动UI线程的AfxBeginThread函数的原型为: CWinThread *AfxBeginThread( //从CWinThread派生的类的 RUNTIME_CLASS CRuntimeClass *pThreadClass,  int nPriority = THREAD_PRIORITY_NORMAL,  UINT nStackSize = 0,  DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);   我们可以方便地使用VC 6.0类向导定义一个继承自CWinThread的用户线程类。下面给出产生我们自定义的CWinThread子类CMyUIThread的方法。  打开VC 6.0类向导,在如下窗口中选择Base Class类为CWinThread,输入子类名为CMyUIThread,点击"OK"按钮后就产生了类CMyUIThread。   其源代码框架为: /////////////////////////////////////////////////////////////////////////////// CMyUIThread threadclass CMyUIThread : public CWinThread{ DECLARE_DYNCREATE(CMyUIThread) protected:  CMyUIThread(); // protected constructor used by dynamic creation  // Attributes public:  // Operations public:  // Overrides  // ClassWizard generated virtual function overrides  //{{AFX_VIRTUAL(CMyUIThread)  public:   virtual BOOL InitInstance();   virtual int ExitInstance();  //}}AFX_VIRTUAL  // Implementation protected:  virtual ~CMyUIThread();  // Generated message map functions  //{{AFX_MSG(CMyUIThread)   // NOTE - the ClassWizard will add and remove member functions here.  //}}AFX_MSG DECLARE_MESSAGE_MAP()};/////////////////////////////////////////////////////////////////////////////// CMyUIThreadIMPLEMENT_DYNCREATE(CMyUIThread, CWinThread)CMyUIThread::CMyUIThread(){}CMyUIThread::~CMyUIThread(){}BOOL CMyUIThread::InitInstance(){ // TODO: perform and per-thread initialization here return TRUE;}int CMyUIThread::ExitInstance(){ // TODO: perform any per-thread cleanup here return CWinThread::ExitInstance();}BEGIN_MESSAGE_MAP(CMyUIThread, CWinThread)//{{AFX_MSG_MAP(CMyUIThread)// NOTE - the ClassWizard will add and remove mapping macros here.//}}AFX_MSG_MAPEND_MESSAGE_MAP()  使用下列代码就可以启动这个UI线程: CMyUIThread *pThread;pThread = (CMyUIThread*)AfxBeginThread( RUNTIME_CLASS(CMyUIThread) );  另外,我们也可以不用AfxBeginThread 创建线程,而是分如下两步完成:  (1)调用线程类的构造函数创建一个线程对象;  (2)调用CWinThread::CreateThread函数来启动该线程。  在线程自身内调用AfxEndThread函数可以终止该线程: void AfxEndThread( UINT nExitCode //the exit code of the thread);  对于UI线程而言,如果消息队列中放入了WM_QUIT消息,将结束线程。  关于UI线程和工作者线程的分配,最好的做法是:将所有与UI相关的操作放入主线程,其它的纯粹的运算工作交给独立的数个工作者线程。  候捷先生早些时间喜欢为MDI程序的每个窗口创建一个线程,他后来澄清了这个错误。因为如果为MDI程序的每个窗口都单独创建一个线程,在窗口进行切换的时候,将进行线程的上下文切换!共4页。 1 2 3 4 :   1、创建和终止线程  在MFC程序中创建一个线程,宜调用AfxBeginThread函数。该函数因参数不同而具有两种重载版本,分别对应工作者线程和用户接口(UI)线程。  工作者线程 CWinThread *AfxBeginThread( AFX_THREADPROC pfnThreadProc, //控制函数 LPVOID pParam, //传递给控制函数的参数 int nPriority = THREAD_PRIORITY_NORMAL, //线程的优先级 UINT nStackSize = 0, //线程的堆栈大小 DWORD dwCreateFlags = 0, //线程的创建标志 LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL //线程的安全属性);  工作者线程编程较为简单,只需编写线程控制函数和启动线程即可。下面的代码给出了定义一个控制函数和启动它的过程: //线程控制函数UINT MfcThreadProc(LPVOID lpParam){ CExampleClass *lpObject = (CExampleClass*)lpParam; if (lpObject == NULL || !lpObject->IsKindof(RUNTIME_CLASS(CExampleClass)))  return - 1; //输入参数非法  //线程成功启动 while (1) {  ...// } return 0;}//在MFC程序中启动线程AfxBeginThread(MfcThreadProc, lpObject);  UI线程  创建用户界面线程时,必须首先从CWinThread 派生类,并使用 DECLARE_DYNCREATE 和 IMPLEMENT_DYNCREATE 宏声明此类。  下面给出了CWinThread类的原型(添加了关于其重要函数功能和是否需要被继承类重载的注释): class CWinThread : public CCmdTarget{ DECLARE_DYNAMIC(CWinThread) public:  // Constructors  CWinThread();  BOOL CreateThread(DWORD dwCreateFlags = 0, UINT nStackSize = 0,LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);  // Attributes  CWnd* m_pMainWnd; // main window (usually same AfxGetApp()->m_pMainWnd)  CWnd* m_pActiveWnd; // active main window (may not be m_pMainWnd)  BOOL m_bAutoDelete; // enables 'delete this' after thread termination  // only valid while running  HANDLE m_hThread; // this thread's HANDLE  operator HANDLE() const;  DWORD m_nThreadID; // this thread's ID  int GetThreadPriority();  BOOL SetThreadPriority(int nPriority);  // Operations  DWORD SuspendThread();  DWORD ResumeThread();  BOOL PostThreadMessage(UINT message, WPARAM wParam, LPARAM lParam);  // Overridables  //执行线程实例初始化,必须重写  virtual BOOL InitInstance();  // running and idle processing  //控制线程的函数,包含消息泵,一般不重写  virtual int Run();  //消息调度到TranslateMessage和DispatchMessage之前对其进行筛选,  //通常不重写  virtual BOOL PreTranslateMessage(MSG* pMsg);  virtual BOOL PumpMessage(); // low level message pump  //执行线程特定的闲置时间处理,通常不重写  virtual BOOL OnIdle(LONG lCount); // return TRUE if more idle processing  virtual BOOL IsIdleMessage(MSG* pMsg); // checks for special messages  //线程终止时执行清除,通常需要重写  virtual int ExitInstance(); // default will 'delete this'  //截获由线程的消息和命令处理程序引发的未处理异常,通常不重写  virtual LRESULT ProcessWndProcException(CException* e, const MSG* pMsg);  // Advanced: handling messages sent to message filter hook  virtual BOOL ProcessMessageFilter(int code, LPMSG lpMsg);  // Advanced: virtual access to m_pMainWnd  virtual CWnd* GetMainWnd();  // Implementation public:  virtual ~CWinThread();  #ifdef _DEBUG   virtual void AssertValid() const;   virtual void Dump(CDumpContext& dc) const;   int m_nDisablePumpCount; // Diagnostic trap to detect illegal re-entrancy  #endif  void CommonConstruct();  virtual void Delete();  // 'delete this' only if m_bAutoDelete == TRUE  // message pump for Run  MSG m_msgCur; // current message public:  // constructor used by implementation of AfxBeginThread  CWinThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam);  // valid after construction  LPVOID m_pThreadParams; // generic parameters passed to starting function  AFX_THREADPROC m_pfnThreadProc;  // set after OLE is initialized  void (AFXAPI* m_lpfnOleTermOrFreeLib)(BOOL, BOOL);  COleMessageFilter* m_pMessageFilter; protected:  CPoint m_ptCursorLast; // last mouse position  UINT m_nMsgLast; // last mouse message  BOOL DispatchThreadMessageEx(MSG* msg); // helper  void DispatchThreadMessage(MSG* msg); // obsolete};  启动UI线程的AfxBeginThread函数的原型为: CWinThread *AfxBeginThread( //从CWinThread派生的类的 RUNTIME_CLASS CRuntimeClass *pThreadClass,  int nPriority = THREAD_PRIORITY_NORMAL,  UINT nStackSize = 0,  DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);   我们可以方便地使用VC 6.0类向导定义一个继承自CWinThread的用户线程类。下面给出产生我们自定义的CWinThread子类CMyUIThread的方法。  打开VC 6.0类向导,在如下窗口中选择Base Class类为CWinThread,输入子类名为CMyUIThread,点击"OK"按钮后就产生了类CMyUIThread。   其源代码框架为: /////////////////////////////////////////////////////////////////////////////// CMyUIThread threadclass CMyUIThread : public CWinThread{ DECLARE_DYNCREATE(CMyUIThread) protected:  CMyUIThread(); // protected constructor used by dynamic creation  // Attributes public:  // Operations public:  // Overrides  // ClassWizard generated virtual function overrides  //{{AFX_VIRTUAL(CMyUIThread)  public:   virtual BOOL InitInstance();   virtual int ExitInstance();  //}}AFX_VIRTUAL  // Implementation protected:  virtual ~CMyUIThread();  // Generated message map functions  //{{AFX_MSG(CMyUIThread)   // NOTE - the ClassWizard will add and remove member functions here.  //}}AFX_MSG DECLARE_MESSAGE_MAP()};/////////////////////////////////////////////////////////////////////////////// CMyUIThreadIMPLEMENT_DYNCREATE(CMyUIThread, CWinThread)CMyUIThread::CMyUIThread(){}CMyUIThread::~CMyUIThread(){}BOOL CMyUIThread::InitInstance(){ // TODO: perform and per-thread initialization here return TRUE;}int CMyUIThread::ExitInstance(){ // TODO: perform any per-thread cleanup here return CWinThread::ExitInstance();}BEGIN_MESSAGE_MAP(CMyUIThread, CWinThread)//{{AFX_MSG_MAP(CMyUIThread)// NOTE - the ClassWizard will add and remove mapping macros here.//}}AFX_MSG_MAPEND_MESSAGE_MAP()  使用下列代码就可以启动这个UI线程: CMyUIThread *pThread;pThread = (CMyUIThread*)AfxBeginThread( RUNTIME_CLASS(CMyUIThread) );  另外,我们也可以不用AfxBeginThread 创建线程,而是分如下两步完成:  (1)调用线程类的构造函数创建一个线程对象;  (2)调用CWinThread::CreateThread函数来启动该线程。  在线程自身内调用AfxEndThread函数可以终止该线程: void AfxEndThread( UINT nExitCode //the exit code of the thread);  对于UI线程而言,如果消息队列中放入了WM_QUIT消息,将结束线程。  关于UI线程和工作者线程的分配,最好的做法是:将所有与UI相关的操作放入主线程,其它的纯粹的运算工作交给独立的数个工作者线程。  候捷先生早些时间喜欢为MDI程序的每个窗口创建一个线程,他后来澄清了这个错误。因为如果为MDI程序的每个窗口都单独创建一个线程,在窗口进行切换的时候,将进行线程的上下文切换!共4页。 1 2 3 4 : 下载本文示例代码


深入浅出Win32多线程设计之MFC的多线程深入浅出Win32多线程设计之MFC的多线程深入浅出Win32多线程设计之MFC的多线程深入浅出Win32多线程设计之MFC的多线程深入浅出Win32多线程设计之MFC的多线程深入浅出Win32多线程设计之MFC的多线程深入浅出Win32多线程设计之MFC的多线程深入浅出Win32多线程设计之MFC的多线程深入浅出Win32多线程设计之MFC的多线程深入浅出Win32多线程设计之MFC的多线程深入浅出Win32多线程设计之MFC的多线程深入浅出Win32多线程设计之MFC的多线程深入浅出Win32多线程设计之MFC的多线程深入浅出Win32多线程设计之MFC的多线程深入浅出Win32多线程设计之MFC的多线程
阅读(112) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~