出处:http://blog.csdn.net/unimen/article/details/6832454
如果用AfxBeginThread()启动worker线程,只能是启动一个函数,即便是启动UI线程,在CWinThread继承的类的,也有很大的限制,其实CWinThread是相当灵活的。
先说AfxBeginThread内部做的工作:
1、在heap中配置一个新的CWinThread对象
2、调用CWinThread::CreateThread()并设定相关属性,使线程以挂起状态产生
3、设定线程优先权
4、调用CWinThread::ResumeThread()
原代码为:
- CWinThread* AFXAPI AfxBeginThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam,
- int nPriority, UINT nStackSize, DWORD dwCreateFlags,
- LPSECURITY_ATTRIBUTES lpSecurityAttrs)
- {
- #ifndef _MT
- pfnThreadProc;
- pParam;
- nPriority;
- nStackSize;
- dwCreateFlags;
- lpSecurityAttrs;
- return NULL;
- #else
- ASSERT(pfnThreadProc != NULL);
- CWinThread* pThread = DEBUG_NEW CWinThread(pfnThreadProc, pParam);
- ASSERT_VALID(pThread);
- if (!pThread->CreateThread(dwCreateFlags|CREATE_SUSPENDED, nStackSize,
- lpSecurityAttrs))
- {
- pThread->Delete();
- return NULL;
- }
- VERIFY(pThread->SetThreadPriority(nPriority));
- if (!(dwCreateFlags & CREATE_SUSPENDED))
- VERIFY(pThread->ResumeThread() != (DWORD)-1);
- return pThread;
- #endif //!_MT)
- }
由此我们要以从CWinThread派生出自己的类,不用AfxBeginThread(),而是仿照其内部工作,自己写,这样就灵活很多,这其中要用到没有公开的CWinThread的一个构造数,和没有公开的成员变量CWinThread::m_pThreadParams;下面先示例代码(摘自Win32多线程程序设计):
- /*
- * NumClass.cpp
- *
- * Sample code for "Multithreading Applications in Win32"
- * This is from Chapter 10, Listing 10-3
- *
- * Demonstrate worker thread startup in MFC
- * without AfxBeginThread.
- *
- * Compile with the IDE or: nmake -f NumClass.mak
- */
- #include <afxwin.h>
- CWinApp TheApp;
- class CUserThread : public CWinThread
- {
- public: // Member functions
- CUserThread(AFX_THREADPROC pfnThreadProc);
- static UINT ThreadFunc(LPVOID param);
- public: // Member data
- int m_nStartCounter;
- private: // The "real" startup function
- virtual void Go();
- };
- CUserThread::CUserThread(AFX_THREADPROC pfnThreadProc)
- : CWinThread(pfnThreadProc, NULL) // Undocumented constructor
- {
- m_bAutoDelete = FALSE;
- // Set the pointer to the class to be the startup value.
- // m_pThreadParams is undocumented,
- // but there is no work-around.
- m_pThreadParams = this;
- }
- int main()
- {
- CUserThread* pThreads[5];
- for (int i=0; i<5; i++)
- {
- // Pass our static member as the startup function
- pThreads[i] = new CUserThread( CUserThread::ThreadFunc );
- // Set the appropriate member variable
- pThreads[i]->m_nStartCounter = i;
- // Start the thread in motion
- VERIFY(
- pThreads[i]->CreateThread() );
- printf("Thread launched %d\n", i);
- }
- for (i=0; i<5; i++)
- {
- WaitForSingleObject(pThreads[i]->m_hThread, INFINITE);
- delete pThreads[i];
- }
- return 0;
- }
- // static
- UINT CUserThread::ThreadFunc(LPVOID n)
- {
- CUserThread* pThread = (CUserThread*)n;
- pThread->Go();
- return 0;
- }
- void CUserThread::Go()
- {
- int n = m_nStartCounter;
- for (int i=0;i<10;i++)
- printf("%d%d%d%d%d%d%d%d\n",n,n,n,n,n,n,n,n);
- }
其中那个未公开的构造函数有两个参数,一个启动函数,一个传给这个函数的参数,这里不需要,因为我们用到了那个示公开的成员变量,这个变量的意思就是指启动参数,即
线程函数的参数;另外我们将m_bAutoDelete设为false,这样对象将不会自动删除。
如果要写自己的线程,可以从上面的类继承,只改写Go虚函数就行了