unsigned long _beginthreadex(
void *security,
unsigned stack_size,
unsigned ( __stdcall *start_address )( void * ),
void *arglist,
unsigned initflag,
unsigned *thrdaddr
);
//第1个参数:安全属性,NULL为默认安全属性
//第2个参数:指定线程堆栈的大小。如果为0,则线程堆栈大小和创建它的线程的相同。一般用0
//第3个参数:指定线程函数的地址,也就是线程调用执行的函数地址(用函数名称即可,函数名称就表示地址)
//第4个参数:传递给线程的参数的指针,可以通过传入对象的指针,在线程函数中再转化为对应类的指针
//第5个参数:线程初始状态,0:立即运行;CREATE_SUSPEND:suspended(悬挂),这样它就无法调度,直到调用ResumeThread()。
//第6个参数:用于记录线程ID的地址
_beginthreadex相对应的退出线程的函数是_endthreadex,CreateThread 对应ExitThread
终止线程:
_endthreadex() 是在线程内部调用的
ExitThread 总是撤消调用的线程,而TerminateThread 能够撤消任何线程
当使用返回或调用ExitThread 的方法撤消线程时,该线程的内存堆栈也被撤消。但是,如果使用TerminateThread ,那么在拥有线程的进程终止运行之前,系统不撤消该线程的堆栈
ExitProcess和TerminateProcess函数也可以用来终止线程的运行。差别在于这些线程将会使终止运行的进程中的所有线程全部终止运行
References:http://blog.sina.com.cn/s/blog_4b4409c30100vmi2.html
(OS:windows)
thread.h
#ifndef _THREAD_SPECIFICAL_H__
#define _THREAD_SPECIFICAL_H__
#include <windows.h>
static unsigned int __stdcall threadFunction(void *);
class Thread {
friend unsigned int __stdcall threadFunction(void *);
public:
Thread();
virtual ~Thread();
int start(void * = NULL);
void * wait();
void stop();
void detach();
static void sleep(unsigned int);
protected:
virtual void * run(void *) = 0;
private:
HANDLE threadHandle;
bool started;
bool detached;
void * param;
unsigned int threadID;
};
#endif
Thread::start()函数是线程启动函数,其输入参数是无类型指针。
Thread::stop()函数中止当前线程。
Thread::sleep()函数让当前线程休眠给定时间,单位为秒。
Thread::run()函数是用于实现线程类的线程函数调用。
Thread::detach()和thread::wait()函数涉及的概念略复杂一些。
thread.cpp
#include "stdafx.h"
#include <process.h>
#include "thread.h"
unsigned int __stdcall threadFunction(void * object)
{
Thread * thread = (Thread *) object;
return (unsigned int ) thread->run(thread->param);
}
Thread::Thread()
{
started = false;
detached = false;
}
Thread::~Thread()
{
stop();
}
int Thread::start(void* pra)
{
if (!started)
{
param = pra;
if (threadHandle = (HANDLE)_beginthreadex(NULL, 0, threadFunction, this, 0, &threadID))
{
if (detached)
{
CloseHandle(threadHandle);
}
started = true;
}
}
return started;
}
//wait for current thread to end.
void * Thread::wait()
{
DWORD status = (DWORD) NULL;
if (started && !detached)
{
WaitForSingleObject(threadHandle, INFINITE);
GetExitCodeThread(threadHandle, &status);
CloseHandle(threadHandle);
detached = true;
}
return (void *)status;
}
void Thread::detach()
{
if (started && !detached)
{
CloseHandle(threadHandle);
}
detached = true;
}
void Thread::stop()
{
if (started && !detached)
{
TerminateThread(threadHandle, 0);
//Closing a thread handle does not terminate
//the associated thread.
//To remove a thread object, you must terminate the thread,
//then close all handles to the thread.
//The thread object remains in the system until
//the thread has terminated and all handles to it have been
//closed through a call to CloseHandle
CloseHandle(threadHandle);
detached = true;
}
}
void Thread::sleep(unsigned int delay)
{
::Sleep(delay);
}
无论在windows中,还是Posix中,主线程和子线程的默认关系是:无论子线程执行完毕与否,一旦主线程执行完毕退出,所有子线程执行都会终止。这时整个进程结束或僵死(部分线程保持一种终止执行但还未销毁的状态,而进程必须在其所有线程销毁后销毁,这时进程处于僵死状态),在第一个例子的输出中,可以看到子线程还来不及执行完毕,主线程的main()函数就已经执行完毕,从而所有子线程终止。
需要强调的是,线程函数执行完毕退出,或以其他非常方式终止,线程进入终止态(请回顾上面说的线程状态),但千万要记住的是,进入终止态后,为线程分配的系统资源并不一定已经释放,而且可能在系统重启之前,一直都不能释放。终止态的线程,仍旧作为一个线程实体存在与操作系统中。(这点在win和unix中是一致的。)而什么时候销毁线程,取决于线程属性。