创建一个在调用进程的虚拟地址空间内执行的线程。

要创建在另一个进程的虚拟地址空间中运行的线程,请使用 CreateRemoteThread函数。

语法

HANDLE CreateThread(LPSECURITY_ATTRIBUTES   lpThreadAttributes,SIZE_T                  dwStackSize,LPTHREAD_START_ROUTINE  lpStartAddress,__drv_aliasesMem LPVOID lpParameter,DWORD                   dwCreationFlags,LPDWORD                 lpThreadId
);

参数

  • lpThreadAttributes

指向SECURITY_ATTRIBUTES 结构的指针,该结构确定子进程是否可以继承返回的句柄。如果 lpThreadAttributesNULL,则无法继承句柄。

结构的lpSecurityDescriptor成员为新线程指定安全描述符。如果lpThreadAttributes为NULL,则线程获取默认安全描述符。线程的默认安全描述符中的ACL来自创建者的主要标志。

  • dwStackSize

堆栈的初始大小,以字节为单位。系统将此值四舍五入到最近的页面。如果此参数为零,则新线程使用可执行文件的默认大小。有关更多信息,请参阅线程堆栈大小。

  • lpStartAddress

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

  • lpParameter

指向要传递给线程的变量的指针。

  • dwCreationFlags

控制线程创建的标志。

含义
0 该线程在创建后立即运行。
CREATE_SUSPENDEDs 0x00000004 线程是在挂起状态下创建的,并且在调用ResumeThread函数之前不会运行 。
STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000在 所述dwStackSize参数指定堆栈的初始保留大小。如果未指定此标志,则dwStackSize指定提交大小。

  • lpThreadId

指向接收线程标识符的变量的指针。如果此参数为 NULL,则不返回线程标识符。

返回值

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

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

请注意,即使lpStartAddress指向数据,代码或无法访问,CreateThread也可能成功 。如果线程运行时起始地址无效,则发生异常,并且线程终止。由于无效的起始地址导致的线程终止被视为线程进程的错误退出。此行为类似于CreateProcess的异步特性,即使它引用无效或缺少动态链接库(DLL),也会创建该进程。

备注

进程可以创建的线程数受可用虚拟内存的限制。默认情况下,每个线程都有一兆字节的堆栈空间。因此,您最多可以创建2,048个线程。如果减小默认堆栈大小,则可以创建更多线程。但是,如果为每个处理器创建一个线程并构建应用程序队列,应用程序维护上下文信息,则应用程序将具有更好的性能。在处理下一个队列中的请求之前,线程将处理队列中的所有请求。

使用THREAD_ALL_ACCESS访问权限创建新的线程句柄。如果在创建线程时未提供安全描述符,则使用创建线程的进程的主令牌为新线程构造默认安全描述符。当调用者尝试使用OpenThread函数访问该线程时,将根据此安全描述符评估调用者的有效令牌以授予或拒绝访问权限。

调用GetCurrentThread 函数时,新创建的线程对自身具有完全访问权限。

Windows Server 2003: 线程对自身的访问权限是通过根据为线程构造的默认安全描述符评估创建线程的进程的主令牌来计算的。如果在远程进程中创建线程,则使用远程进程的主令牌。因此,在调用GetCurrentThread时,新创建的线程可能会减少对自身的访问权限。某些访问权限(包括THREAD_SET_THREAD_TOKENTHREAD_GET_CONTEXT)可能不存在,从而导致意外故障。因此,建议不要在模仿其他用户时创建线程。

如果线程是在可运行状态下创建的(即,如果未使用CREATE_SUSPENDED标志),则线程可以在CreateThread返回之前开始运行,特别是在调用者接收到创建的线程的句柄和标识符之前。

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

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

当线程终止时,线程对象获得信号状态,满足在对象上等待的任何线程。

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

ExitProcess, ExitThread, CreateThread, CreateRemoteThread的功能,以及正在启动的处理(如通过一个调用的结果 CreateProcess)的过程中是彼此之间串行化。这些事件中只有一个可以一次发生在地址空间中。这意味着以下限制包含:

在进程启动和DLL初始化例程期间,可以创建新线程,但是在为进程执行DLL初始化之前它们不会开始执行。
进程中只有一个线程可以一次处于DLL初始化或分离例程中。
在DLL初始化或分离例程中没有线程之前,ExitProcess不会完成。
调用C运行时库(CRT)的可执行文件中的线程应使用_beginthreadex和_endthreadex函数进行线程管理,而不是 CreateThread和 ExitThread ; 这需要使用CRT的多线程版本。如果使用CreateThread创建的线程调用CRT,则CRT可以在低内存条件下终止进程。
Windows Phone 8.1: Windows Phone 8.1及更高版本上的Windows Phone应用商店支持此功能。

Windows 8.1和Windows Server 2012 R2:Windows 8.1,Windows Server 2012 R2及更高版本上的Windows应用商店应用程序支持此功能。

例子
有关示例,请参阅 创建线程。

CreateThread函数相关推荐

  1. 一个基于C++的多线程编程实例(CreateThread函数)

    本博客主要总结了基于C++的多线程函数CreateThread,互斥锁(或者称资源独占)函数CreateMutex,等待资源函数WaitForSingleObject,关闭线程函数(其实是关闭线程的句 ...

  2. 使用CreateThread函数创建线程

    线程是进程中的一个实体,是被系统独立调度和分派的基本单位.一个进程可以拥有多个线程,但是一个线程必须有一个进程.线程自己不拥有系统资源,只有运行所必须的一些数据结构,但它可以与同属于一个进程的其它线程 ...

  3. c语言createthread函数,C++中CreateThread函数创建线程的用法和实例

    CreateThread是一种微软在Windows API中提供了建立新的线程的函数,该函数在主线程的基础上创建一个新线程.线程终止运行后,线程对象仍然在系统中,必须通过CloseHandle函数来关 ...

  4. c语言createthread函数用法,C++多线程函数CreateThread如何使用?

    C++ CreateThread函数如何传递this指针作为参数 C++多线程函数CreateThread如何使用? #include #include using namespace std; /* ...

  5. CreateThread函数用法

    CreateThread步骤 CreateThread将在主线程的基础上创建一个新线程,大致做如下步骤: 1.在内核对象中分配一个线程标识/句柄,可供管理,由CreateThread返回 2.把线程退 ...

  6. CreateThread()函数使用

    函数所在头文件 #include<windows.h> CreateThread()函数原型 HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpTh ...

  7. C++使用CreateThread函数创建线程

    使用CreateThread函数创建线程 线程是进程中的一个实体,是被系统独立调度和分派的基本单位.一个进程可以拥有多个线程,但是一个线程必须有一个进程.线程自己不拥有系统资源,只有运行所必须的一些数 ...

  8. CreateThread()函数及_beginthreadex()函数

    CreateThread():创建一个线程可以调用进程的虚拟地址空间内执行.创建的线程终止运行后,线程对象仍然在系统中,必须通过CloseHandle函数来关闭该线程对象. 函数原型: HANDLE ...

  9. 多线程CreateThread函数的用法及注意事项

    当使用CreateProcess调用时,系统将创建一个进程和一个主线程.CreateThread将在主线程的基础上创建一个新线程,大致做如下步骤: 1在内核对象中分配一个线程标识/句柄,可供管理,由C ...

最新文章

  1. JAVA EE Eclipse下配置Tomcat服务器
  2. 华三交换机ping不通用户但用户_H3C故障常见故障及解决方案
  3. 利用indent格式化源文件的脚本
  4. Install VMware tools 解决(物理主机WIN7X64和VM下的REHAT LINUX AS4共享文件)
  5. 何时才使用https访问项目
  6. 浅析MyBatis执行器原理
  7. 这可能不只是一篇面经(BAT面试)
  8. MATLAB绘图——加强篇
  9. 日本外贸市场开发攻略
  10. 批量保存网页为html文件的几种方法
  11. FSCE: Few-Shot Object Detection via Contrastive Proposal Encoding个人理解
  12. 线性代数笔记8:矩阵的对角化
  13. 2019年安徽省大数据与人工智能应用赛总结---本科组
  14. 超爆笑段子大集锦 你要不笑我自宫
  15. TensorFlow Object Detection API 多GPU 卡平行计算,加速模型训练速度教学
  16. 使用PHP将任意格式的日期转换为Unix时间戳
  17. Ubuntu16.04安装联想LJ2600D打印机驱动程序
  18. Android之SQLite数据库的使用
  19. DW 2023年1月Free Excel 第六次打卡 查找函数
  20. 计算机控制反激变换器控制,SPWM控制的交叉反激变换器设计.pdf

热门文章

  1. php查询表导出excel文件路径,Thinkphp5如何将导出的excel表格存储到服务器中项目目录的指定目录中?...
  2. c99什么意思_C语言中-是什么意思啊?
  3. 解决 idea 复制jsp 文件过来页面报404
  4. 命令行 蓝牙_Ubuntu使用BlueZ驱动蓝牙dongle
  5. leetcode112 路径总和
  6. leetcode32 最长有效括号
  7. 算法(2)-二叉树的遍历(递归/迭代)python实现
  8. 使用Python作为计算器
  9. Hello OpenGL——OpenGL在Visual c++6.0安装和配置
  10. java蓝桥杯 试题-基础练习-十六进制转八进制