灵活运用CWinThread,构造自己的worker线程

出处:http://blog.csdn.net/unimen/article/details/6832454

如果用AfxBeginThread()启动worker线程,只能是启动一个函数,即便是启动UI线程,在CWinThread继承的类的,也有很大的限制,其实CWinThread是相当灵活的。

先说AfxBeginThread内部做的工作:

1、在heap中配置一个新的CWinThread对象

2、调用CWinThread::CreateThread()并设定相关属性,使线程以挂起状态产生

3、设定线程优先权

4、调用CWinThread::ResumeThread()

原代码为:

[cpp]  view plain copy
  1. CWinThread* AFXAPI AfxBeginThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam,  
  2.     int nPriority, UINT nStackSize, DWORD dwCreateFlags,  
  3.     LPSECURITY_ATTRIBUTES lpSecurityAttrs)  
  4. {  
  5. #ifndef _MT  
  6.     pfnThreadProc;  
  7.     pParam;  
  8.     nPriority;  
  9.     nStackSize;  
  10.     dwCreateFlags;  
  11.     lpSecurityAttrs;  
  12.   
  13.     return NULL;  
  14. #else  
  15.     ASSERT(pfnThreadProc != NULL);  
  16.   
  17.     CWinThread* pThread = DEBUG_NEW CWinThread(pfnThreadProc, pParam);  
  18.     ASSERT_VALID(pThread);  
  19.   
  20.     if (!pThread->CreateThread(dwCreateFlags|CREATE_SUSPENDED, nStackSize,  
  21.         lpSecurityAttrs))  
  22.     {  
  23.         pThread->Delete();  
  24.         return NULL;  
  25.     }  
  26.     VERIFY(pThread->SetThreadPriority(nPriority));  
  27.     if (!(dwCreateFlags & CREATE_SUSPENDED))  
  28.         VERIFY(pThread->ResumeThread() != (DWORD)-1);  
  29.   
  30.     return pThread;  
  31. #endif //!_MT)  
  32. }  

由此我们要以从CWinThread派生出自己的类,不用AfxBeginThread(),而是仿照其内部工作,自己写,这样就灵活很多,这其中要用到没有公开的CWinThread的一个构造数,和没有公开的成员变量CWinThread::m_pThreadParams;下面先示例代码(摘自Win32多线程程序设计):

[cpp]  view plain copy
  1. /* 
  2.  * NumClass.cpp 
  3.  * 
  4.  * Sample code for "Multithreading Applications in Win32" 
  5.  * This is from Chapter 10, Listing 10-3 
  6.  * 
  7.  * Demonstrate worker thread startup in MFC 
  8.  * without AfxBeginThread. 
  9.  * 
  10.  * Compile with the IDE or: nmake -f NumClass.mak 
  11.  */  
  12.   
  13. #include <afxwin.h>  
  14.   
  15. CWinApp TheApp;  
  16.   
  17.   
  18. class CUserThread : public CWinThread  
  19. {  
  20. public:  // Member functions  
  21.     CUserThread(AFX_THREADPROC pfnThreadProc);  
  22.   
  23.     static UINT ThreadFunc(LPVOID param);  
  24.   
  25. public:  // Member data  
  26.     int m_nStartCounter;  
  27.   
  28. private// The "real" startup function  
  29.     virtual void Go();  
  30. };  
  31.   
  32. CUserThread::CUserThread(AFX_THREADPROC pfnThreadProc)  
  33.  : CWinThread(pfnThreadProc, NULL)  // Undocumented constructor  
  34. {  
  35.     m_bAutoDelete = FALSE;  
  36.   
  37.     // Set the pointer to the class to be the startup value.  
  38.     // m_pThreadParams is undocumented,  
  39.     // but there is no work-around.  
  40.     m_pThreadParams = this;  
  41. }  
  42.   
  43.   
  44. int main()  
  45. {  
  46.     CUserThread* pThreads[5];  
  47.   
  48.     for (int i=0; i<5; i++)  
  49.     {  
  50.         // Pass our static member as the startup function  
  51.         pThreads[i] = new CUserThread( CUserThread::ThreadFunc );  
  52.   
  53.         // Set the appropriate member variable  
  54.         pThreads[i]->m_nStartCounter = i;  
  55.   
  56.         // Start the thread in motion  
  57.         VERIFY(  
  58.           pThreads[i]->CreateThread() );  
  59.         printf("Thread launched %d\n", i);  
  60.     }  
  61.   
  62.     for (i=0; i<5; i++)  
  63.     {  
  64.         WaitForSingleObject(pThreads[i]->m_hThread, INFINITE);  
  65.         delete pThreads[i];  
  66.     }  
  67.   
  68.     return 0;  
  69. }  
  70.   
  71.   
  72. // static  
  73. UINT CUserThread::ThreadFunc(LPVOID n)  
  74. {  
  75.     CUserThread* pThread = (CUserThread*)n;  
  76.     pThread->Go();  
  77.     return 0;  
  78. }  
  79.   
  80. void CUserThread::Go()  
  81. {  
  82.     int n = m_nStartCounter;  
  83.     for (int i=0;i<10;i++)  
  84.         printf("%d%d%d%d%d%d%d%d\n",n,n,n,n,n,n,n,n);  
  85. }  

其中那个未公开的构造函数有两个参数,一个启动函数,一个传给这个函数的参数,这里不需要,因为我们用到了那个示公开的成员变量,这个变量的意思就是指启动参数,即

线程函数的参数;另外我们将m_bAutoDelete设为false,这样对象将不会自动删除。

如果要写自己的线程,可以从上面的类继承,只改写Go虚函数就行了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值