操作系统提供的SDK API CreateThread原型如下:
HANDLE WINAPI CreateThread(
__in LPSECURITY_ATTRIBUTES lpThreadAttributes ,
__in SIZE_T dwStackSize ,
__in LPTHREAD_START_ROUTINE lpStartAddress ,
__in LPVOID lpParameter ,
__in DWORD dwCreationFlags ,
__out LPDWORD lpThreadId
);
lpThreadAttributes: 指向SECURITY_ATTRIBUTES型态的结构的指针。在Windows 98中忽略该参数。在Windows NT中,设为NULL,表示使用缺省值。
dwStackSize: 线程堆栈大小,一般为0,在任何情况下,Windows根据需要动态延长堆栈的大小。可以使用链接器的/STACK: [reserve ] [,commit] 来控制。
reserve设置系统为线程栈预留多少地址空间,默认为1M;commit表示最初为栈预料的地址空间调拨多少物理内存空间,默认是1个页面。
lpStartAddress: 指向线程函数的指针,形式:@函数名,函数名称没有限制,但是必须以下列形式声明:
DWORD WINAPI ThreadProc (LPVOID pParam) ,格式不正确将无法调用成功。
lpParameter :向线程函数传递的参数,是一个指向结构的指针,不需传递参数时,为NULL。
dwCreationFlags :如果设置为CREATE_SUSPENDED,线程创建后被挂起,只有当你调用ResumeThread 的时候它才继续进行。
如果设置为0的话,在线程创建后立即执行。
如果设置为STACK_SIZE_PARAM_IS_A_RESERVATION ,则使用dwStackSize 标记中的reserve,否则的话是commit。
在Windows 2000/NT and Windows Me/98/95下 STACK_SIZE_PARAM_IS_A_RESERVATION 无效.
lpThreadId :保存新线程的id。
函数返回值: 若函数成功,返回线程句柄;函数失败返回FALSE。
下面举例说明:
SDKThreading.h
SDKThreading.cpp
对于线程的终止,大体有如下4种:
1.线程函数的返回,这种方式强烈建议使用。
2.线程自己调用ExitThread函数自杀(囧~~自杀不好,避免使用)
3.另一个线程调用TerminateThread函数(他杀~这种方式也应当避免)
4.包含线程的进程强制终止(这种方式也应当避免)
对于线程函数的返回,这是最好的处理方式,线程函数正常返回,会处理下面4件事情:
1.线程函数中创建的所有C++对象都通过其析构函数被正常析构。
2.操作系统正确释放线程栈使用的内存。
3.操作系统把线程的退出代码设为线程函数的返回值。
4.系统减少线程内核对象的使用计数。
在线程终止的时候,会处理下面几件事情:
1.线程拥有的所有用户对象句柄会被释放。在Windows中,大多对象都是包含了“创建这些对象的线程”的进程拥有。但一个线程有2个用户对象:窗口和钩子。一个线程终止时,系统会自动销毁由线程创建或安装的任何窗口,并卸载由线程创建或安装的任何钩子。其他对象只有在拥有线程的进程终止的时候才会被销毁。
2.线程的退出代码从STILL_ACTIVE变成传给ExitThread或TerminateThread的代码
3.线程内核对象的状态变为触发状态。
4.如果线程是进程的最后一个活动进程,系统认为进程也终止了。
5.线程内核对象的使用计数减为1.
你可以使用GetExitCodeThread来判断某一个线程是否终止了,详情参看MSDN。
后面,还有C++库和MFC库的_beginthreadex和afxBeginThread函数的详细说明。
多线程编程(一)——CreateThread
最新推荐文章于 2021-09-27 22:44:47 发布