多线程编程(一)——CreateThread

来源:互联网 发布:手机页游刷元宝软件 编辑:程序博客网 时间:2024/04/30 04:18

  操作系统提供的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函数的详细说明。

 

 

本系列示例代码下载