一、创建线程
线程内核对象就是一个包含了线程状态信息的数据结构。每次对CreateThread 的成功调用,系统都会在内部为其分配一个内核对象。创建线程方法:
HANDLE WINAPI CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 线程安全属性
SIZE_T dwStackSize, // 线程堆栈大小
LPTHREAD_START_ROUTINE lpStartAddress, // 线程函数地址
LPVOID lpParameter, // 线程函数参数
DWORD dwCreationFlags, // 指定线程是否立即启动
LPDWORD lpThreadId // 存储线程ID号
);
uintptr_t _beginthreadex(
void *security, // 线程安全属性
unsigned stack_size, // 线程堆栈大小
unsigned ( *start_address )( void * ), //线程函数地址
void *arglist, //传递给线程函数的参数
unsigned initflag, // 指定线程是否立即启动
unsigned *thrdaddr // 存储线程ID号
);
其中CreateThread的参数:
lpThreadAttributes:指向一个SECURITY_ATTRIBUTES结构的指针,该结构决定该线程的安全属性,一般置为NULL对应默认安全属性。
dwStackSize:指定了线程的堆栈深度,如果为0,则线程堆栈大小和创建它的线程的相同。一般也都设置为0。
lpStartAddress:表示新线程开始执行时代码所在的函数的地址,即线程起始地址。一般情况为(LPTHREAD_START_ROUTINE)ThreadFunc; ThreadFunc是线程函数名。
lpParameter:指定了线程执行时传递给线程的32位参数,即线程函数的参数;可传递指针;
dwCreationFlags:控制线程创建时附加标志,可以取两种值。0--创建后立即开始;CREATE_SUSPENDED--线程产生后立即处于挂起状态,并不马上执行,直到函数ResumeThread被调用。
lpThreadId:该参数返回所创建线程的ID;如果创建成功则返回线程的句柄,否则返回NULL;
线程上下文反应了线程上次执行的寄存器状态,来保证线程之间切换(即还原现场)。
计数器,调用一次OpenThread(CreateThread ),计数器加1,CloseThread(CloseHandle)计数器减一。当计数器值为0时,没有线程使用该内核对象,系统收回内存。计数器的初始值是2(主线程是1,创建的线程是2)。
另外更建议使用_beginthreadex而不是CreateThread,虽然_beginthreadex底层实现也是调用CreateThread,但是其具有更多的安全处理。
二、线程终止
线程函数退出。
线程使用的堆栈被释放。
dwExitCode设置为线程函数的返回值。
递减内核中的code值,让内核的引用计数减一。
// 结束线程调用,终止自己
VOID WINAPI ExitThread(
__in DWORD dwExitCode // 线程结束时的退出码
);
// 由当前线程终止其他线程
BOOL WINAPI TerminateThread(
__in_out HANDLE hThread, // 终止的线程句柄
__in DWORD dwExitCode // 退出码
);
// 进程退出
VOID WINAPI ExitProcess(
__in UINT uExitCode // 退出码
);
void _endthreadex(
unsigned retval // 退出码
);
三、栗子
#include "stdafx.h"
#include <iostream>
#include <string>
#include "windows.h"
#include <process.h>
using namespace std;
struct THREAD_STRUCT
{
string name;
int num;
char* descri;
};
unsigned int WINAPI ThreadFunc(LPVOID lpParam)
{
cout << "这个线程的名字是:" << ((THREAD_STRUCT*)lpParam)->name << endl;
cout << "这个线程的编号是:" << ((THREAD_STRUCT*)lpParam)->num << endl;
cout << "这个线程的想说:" << ((THREAD_STRUCT*)lpParam)->descri << endl;
return 0;
}
int main(int argc, char** argv)
{
THREAD_STRUCT tStr;
tStr.name = "线程一号";
tStr.num = 7;
tStr.descri = "I am Seven";
HANDLE hThreadHand = NULL;
unsigned int dwThreadID;
//
//hThreadHand = CreateThread(NULL, NULL, ThreadFunc, &tStr, 0, &dwThreadID);
hThreadHand = (HANDLE)_beginthreadex(NULL, NULL, ThreadFunc, &tStr, 0, &dwThreadID);
CloseHandle(hThreadHand);
system("pause");
return 0;
}