一、介绍:(与进程一样,由两部分组成:线程内核对象,地址空间(堆栈)),但线程的开销比线程小很多;能简化用户界面;充分利用CPU。
二、线程函数:
a) 线程进入点函数:
DWORD WINAPI ThreadFunc(PVOID, pvParam){
DWORD dwResult = 0 ;
…
return (dwResult);
}
b) 主线程进入点函数:main, wmain, WinMain, wWinMain
c) 必须有返回值
三、创建线程的函数:
HANDLE CreateThread(
PSECURITY_ATTRIBUTES psa, //NULL,默认安全属性
DWORD cbStack, //设定地址空间大小,可以使用链接程序的/STACK开关控制
PTHREAD_START_ROUTINE pfnStartAddr, //线程函数的地址
PVOID pvParam, //可用于传值,但是,如果是局部变量传入,可能导致访问违例,使用线程同步技术来处理!
DWORD fdwCreate,//=NULL,立即调度;=CREATE_SUSPENDED,暂停执行
PDWORD pdwThreadID);//可传递NULL,但win98不行!
四、建议使用CRT函数创建线程:_beginthreadex , _endthreadex. (TLS线程本地存储),但不建议使用_beginthread和_endthread。
unsigned long _beginthreadex(
void *security,
unsigned stack_size,
unsigned (*start_address)(void *),
void *arglist,
unsigned initflag,
unsigned *thrdaddr);
五、终止线程运行,方法:
a) 线程函数返回(最好)
b) ExitThread(最好不用,C++资源未释放,但内存堆栈被撤销)
c) TerminateThread(应避免使用,内存堆栈不被撤销)
d) 包含线程的进程终止。
六、查询线程
a) 是否已经终止:
BOOL GetExitCodeThread(HANDLE hThread, //线程句柄
PDWORD pdwExitCode);//如线程结束,则指向返回值,否则=STILL_ACTIVE
b) 获取进程/线程的伪句柄(当前调用函数的句柄),CloseHandle将失效:
HANDLE GetCurrentProcess();
HANDLE GetCurrentThread();
c) 获取ID:
DWORD GetCurrentProcessId(); DWORD GetCurrentThreadId();
d) 将伪句柄变成实句柄DuplicateHandle:
HANDLE hThreadParent;
BOOL DuplicateHandle(
GetCurrentProcess(),
GetCurrentThread(),
GetCurrentProcess(),
&hThreadParent,
0, FALSE, DUPLICATE_SAME_ACCESS);