MFC中线程创建的一般方法

说到线程的创建,常用到的函数有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根本谈不上封装,数据的保存也不是很清楚,大量的变量要定义成全局变量或在线程函数里定义如果调用某个函数的话,还要通过全局变量或是参数传值,要返回很多值的话也不方便,总之,用面向对象的方法使用它是做好的。




发布了21 篇原创文章 · 获赞 9 · 访问量 12万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章