以下内容摘抄自《Visual C++开发技术大全》,为学习笔记。
线程分为用户界面线程和工作者线程(又称为后台线程或辅助线程)两种。
一、用户界面线程
用户界面线程通常用来处理用户的输入并响应用户生成的事件和消息;不需要用户输入的就是工作者线程。在MFC中,CWinAPP 对象就是一个用户界面线程,用户界面线程一般都是主线程,在Windows操作系统下随应用程序启动而自动创建,随应用程序的退出而终止。
创建用户界面线程的方法如下。先从 CWinTread 派生一个类,同时必须用 DECLARE_DYNCREATE 和 IMPLEMENT_DYNCREATE 来声明和实现这个 CWinThread 派生类,然后根据需要重载该派生类的一些成员函数,如: ExitInstance、InitInstance、OnIdle、PreTranslateMessage 等函数,最后调用 AfxBeginThread 函数来启动用户界面线程。注意 AfxBeginThread 函数有两个版本,要用到下面版本。
CWinThread* AfxBeginThread( CRuntimeClass* pThreadClass, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );
关于用户界面线程的使用详见以下两篇文章:
MFC用户界面多线程实例1
MFC用户界面多线程实例2
二、工作者线程
工作者线程用来执行程序的后台处理任务,比如计算、压缩、对文件或串口的读写操作等。它和用户界面线程的区别是它不用CWinThread类派生来创建,它的创建主要通过 AfxBeginThread 函数的另一个版本来实现,原型如下:
CWinThread* AfxBeginThread( AFX_THREADPROC pfnThreadProc, LPVOID pParam, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );
线程操作
一、创建线程
创建线程的方法很多,除了 AfxBeginThread 函数外,还有 Win32 API 函数 CreateThread 、 _BeginThreadex 。
关于CreateThread 、 _BeginThreadex, 如果线程函数中有用到标准C库函数的话,就要选择 _BeginThreadex 来创建线程。
HANDLE WINAPI CreateThread( _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ SIZE_T dwStackSize, _In_ LPTHREAD_START_ROUTINE lpStartAddress, _In_opt_ LPVOID lpParameter, _In_ DWORD dwCreationFlags, _Out_opt_ LPDWORD lpThreadId );
返回值:成功返回线程句柄,失败返回 NULL 。
_BeginThreadex 的参数和 CreateThread 一样。
二、终止线程
结束线程的方法很多,一般情况下是线程事情做完正常返回,常用的有ExitThread 和 TerminateThread 两个函数。这两个函数终止的线程不同, ExitThread 只能在线程中使用并且只能终止其本身,调用该函数终止线程时可以让操作系统去清除线程使用过的系统资源,但是 new 建立的 C++ 对象资源不能由 ExitThread 来终止;相对于 ExitThread 函数, Terminate 的功能更强大, 它可以用来终止本线程或本线程外的任何线程。下面详细介绍这两个函数。
VOID WINAPI ExitThread( _In_ DWORD dwExitCode );
BOOL WINAPI TerminateThread( _Inout_ HANDLE hThread, _In_ DWORD dwExitCode );成功返回非0,失败返回0。
三、示例。