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

如果用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虚函数就行了

你可能感兴趣的:(thread,function,Constructor,pthreads,attributes,multithreading)