說到線程的創建,常用到的函數有3類,CreateThread、_beginthread或_beginthreadex、AfxrBeginThread,以前剛學多線程的時候,只要是創建線程,我一般都是用的_beginthread或_beginthreadex,因爲用的多,也就比較熟悉了,但是,線程創建時是要分情況的,控制檯下用_beginthread或_beginthreadex比較多,下面看看函數的原型
unsigned long _beginthread( void( __cdecl *start_address )( void * ),
unsigned stack_size, void *arglist );
unsigned long _beginthreadex( void *security, unsigned stack_size,
unsigned ( __stdcall *start_address )( void * ),
void *arglist, unsigned initflag,
unsigned *thrdaddr );
比較一下,第一個線程創建函數沒有線程ID參數和初始狀態參數的,返回值是線程句柄,涉及到句柄的一般在win32或控制檯用的多,都是直接調用API的。下面看看CreateThread函數
HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId);
這個函數看參數就知道與內核對象有關,可以設置安全屬性、參數傳遞、初始狀態、線程ID等參數,一般適用於WindowsAPI編程。下面重點說說AfxBeginThread這個函數,這個函數多數用在MFC中,下面我們看看函數原型。
CWinThread* AfxBeginThread( AFX_THREADPROC pfnThreadProc,
LPVOID pParam,
int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = 0, DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );
CWinThread* AfxBeginThread( CRuntimeClass* pThreadClass,
int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = 0, DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );
先看第二個函數,第一個參數是CRunTime類指針,這個一般創建界面線程,它可以處理空閒或是運行時候的任何事件,一般用於與界面有關的,第一個函數適用於創建工作者線程,比較兩個函數發現第二個函數沒有pParam參數,這個是用於傳遞個線程函數的參數,是一個空指針,你可以讓他指向任意對象。如果你創建的是MFC程序,推薦你使用第一個,下面是線程創建的常規模式,某位牛人推薦的哦。
自定義線程類CMyThread
// MyThread.h: interface for the CMyThread class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_MYTHREAD_H__C4659046_73FE_42D8_A9EB_3250C606E3B3__INCLUDED_)
#define AFX_MYTHREAD_H__C4659046_73FE_42D8_A9EB_3250C606E3B3__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CMyThread
{
public:
CWinThread* pThread;
void Run();
CWinThread* CreatThread();
void ExitThread();
CMyThread();
virtual ~CMyThread();
};
#endif // !defined(AFX_MYTHREAD_H__C4659046_73FE_42D8_A9EB_3250C606E3B3__INCLUDED_)
cpp文件// MyThread.cpp: implementation of the CMyThread class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "thread.h"
#include "MyThread.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
UINT DrawTree( LPVOID pParam );
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMyThread::CMyThread()
{
}
CMyThread::~CMyThread()
{
}
CWinThread* CMyThread::CreatThread()
{
pThread = AfxBeginThread(DrawTree, this, THREAD_PRIORITY_NORMAL, 0, 0, NULL );
return pThread;
}
void CMyThread::Run()
{
MessageBox(NULL,"線程創建!!",NULL, MB_OKCANCEL);
}
void CMyThread::ExitThread()
{
}
UINT DrawTree( LPVOID pParam )
{
CMyThread* pMyThread = (CMyThread*)pParam;
pMyThread->Run();
return 0;
}
這樣寫的好處是線程的創建於執行函數都在被封裝在類裏面,你需要的變量,只需要在類裏面定義就ok了,這比起直接用AfxBeginThread來說要好的多,直接用AfxBeginThread根本談不上封裝,數據的保存也不是很清楚,大量的變量要定義成全局變量或在線程函數裏定義如果調用某個函數的話,還要通過全局變量或是參數傳值,要返回很多值的話也不方便,總之,用面向對象的方法使用它是做好的。