CreateThread创建线程函数详细讲解

  • Post author:
  • Post category:其他


CreateThread

CreateThread函数创建一个要在调用进程的地址空间中执行的线程。(MSDN讲解如下)

处理CreateThread (
LPSECURITY_ATTRIBUTES lpThreadAttributes, //指向安全属性的指针
dwStackSize, //初始线程堆栈大小
说明:LPTHREAD_START_ROUTINE lpStartAddress, //指向线程函数的指针。-
LPVOID lpParameter, //新线程的参数
DWORD dwCreationFlags, // create flags
接收线程ID的指针
);

实例: m_hSendThread = CreateThread(NULL,0,SendThread,this,0,&m_dwSendThreadID);

倒数第二个参数为0表示线程创建后立即运行

最后一个参数不为空,表示运行后有返回值

参数

lpThreadAttributes

指向SECURITY_ATTRIBUTES结构的指针,该结构决定子进程是否可以继承返回的句柄。如果lpThreadAttributes为空,则不能继承句柄。

结构的lpSecurityDescriptor成员为新线程指定一个安全描述符。如果lpThreadAttributes为空,线程将获得一个默认的安全描述符。

dwStackSize

指定堆栈的初始提交大小,以字节为单位。系统将这个值舍入到最近的页面。如果此值为零,或者小于默认的提交大小,则默认情况下使用与调用线程相同的大小。有关更多信息,请参见线程堆栈大小。

lpStartAddress

指向由线程执行的类型为lpthread_start_例程的应用程序定义的函数的指针,并表示线程的起始地址。有关thread函数的更多信息,请参见ThreadProc。

lpParameter

指定传递给线程的单个32位参数值。

dwCreationFlags

指定控制线程创建的附加标志。如果指定了CREATE_SUSPENDED标志,则线程将以挂起状态创建,并且在调用ResumeThread函数之前不会运行。如果该值为零,则线程在创建后立即运行。此时,不支持其他值。

lpThreadId

指向接收线程标识符的32位变量的指针。

如果该参数为空,则不返回线程标识符。

Windows 95和Windows 98:此参数可能不为空。

返回值

如果函数成功,则返回新线程的句柄。

如果函数失败,返回值为NULL。要获取扩展的错误信息,请调用GetLastError。

只有在32位程序的上下文中调用CreateThread时才会成功。当16位程序调用一个32位DLL时,该DLL不能创建额外的线程。

讲话

使用THREAD_ALL_ACCESS创建新线程句柄。如果没有提供安全描述符,则可以在需要线程对象句柄的任何函数中使用该句柄。当提供安全描述符时,将在授予访问权之前对句柄的所有后续使用执行访问检查。如果访问检查拒绝访问,请求进程就不能使用句柄来访问线程。

线程执行从lpStartAddress参数指定的函数开始。如果此函数返回,则使用DWORD返回值终止对ExitThread函数的隐式调用中的线程。使用GetExitCodeThread函数获取线程的返回值。

即使lpStartAddress指向数据、代码或不可访问,CreateThread函数也可能成功。如果线程运行时起始地址无效,则发生异常,线程终止。由于无效的开始地址而导致的线程终止将作为线程进程的错误退出处理。这种行为类似于CreateProcess的异步本质,即使它引用无效或缺少动态链接库(dll),也会创建进程。

线程的优先级是THREAD_PRIORITY_NORMAL。使用GetThreadPriority和SetThreadPriority函数来获取和设置线程的优先级值。

当一个线程终止时,线程对象达到一个有信号状态,满足任何正在等待该对象的线程。

线程对象一直保留在系统中,直到线程终止,并且通过调用CloseHandle关闭了对它的所有句柄。

ExitProcess、ExitThread、CreateThread、CreateRemoteThread函数和正在启动的进程(作为CreateProcess调用的结果)在一个进程内彼此序列化。在地址空间中一次只能发生一个事件。这意味着以下限制仍然有效:

在进程启动和DLL初始化过程中,可以创建新线程,但是在进程完成DLL初始化之前,它们不会开始执行。

一个进程中一次只能有一个线程处于DLL初始化或分离例程中。

ExitProcess直到没有线程在其DLL初始化或分离例程时才返回。

使用C运行库函数的线程应该使用beginthread和endt



版权声明:本文为qq_41476542原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。