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

函数原型:

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

参数解释:
lpThreadAttributes
指向SECURITY_ATTRIBUTES 结构的指针,该结构确定子进程是否可以继承返回的句柄。如果 lpThreadAttributes为NULL,则不能继承该句柄。
结构的lpSecurityDescriptor成员为新线程指定一个安全描述符。如果lpThreadAttributes为NULL,则线程获取默认的安全描述符。线程的默认安全描述符中的ACL来自创建者的主要令牌。
dwStackSize
堆栈的初始大小,以字节为单位。系统将此值舍入到最接近的页面。如果此参数为零,则新线程将使用可执行文件的默认大小。有关更多信息,请参见 线程堆栈大小。
lpStartAddress
指向要由线程执行的应用程序定义的函数的指针。该指针表示线程的起始地址。有关线程函数的更多信息,请参见 ThreadProc。
lpParameter
指向要传递给线程的变量的指针。
dwCreationFlags
控制线程创建的标志。

含义
0 线程在创建后立即运行
CREATE_SUSPENDED 该线程以挂起状态创建,并且直到调用ResumeThread函数后才运行 。
STACK_SIZE_PARAM_IS_A_RESERVATION 所述dwStackSize参数指定堆栈的初始保留大小。如果未指定此标志,则dwStackSize指定提交大小。

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


返回值

如果函数成功,则返回值是新线程的句柄。
如果函数失败,则返回值为NULL。可以调用GetLastError函数查看错误


创建示例
...//初始化函数//线程函数
DWORD WINAPI THreadFun(LPVOID lpParameter)
{for(int i = 0;i < 5;++i){cout << "子进程:i=" << i << endl;Sleep(100);}return 0;
}
int main()
{//创建线程 thread保存线程的句柄HANDLE thread = CreateThread(NULL,0,THreadFun,NULL,0,NULL);//关闭线程CloseHandle(thread);
}


_beginthreadex():用于创建一个线程。CreateThread()函数时Windows提供的API接口,但是在C/C++语言中使用_beginthreadex()创建函数。标准C运行库与多线程存在矛盾。Windows提供解决矛盾的办法每个线程都将拥有自己专用的一块内存区域来供标准C运行库中所有有需要的函数使用。而这块内存区域的创建由_beginthreadex()来负责。

函数原型:

uintptr_t _beginthreadex( // NATIVE CODEvoid *security,unsigned stack_size,unsigned ( __stdcall *start_address )( void * ),void *arglist,unsigned initflag,unsigned *thrdaddr
);

参数解释:
security
安全属性,为NULL时表示默认安全。
start_address
开始执行新线程的例程的起始地址。对于_beginthread,调用约定是__cdecl(对于本机代码)或__clrcall(对于托管代码);对于_beginthreadex,它可以是__stdcall(对于本机代码)或__clrcall(对于托管代码)。

/*函数执行成功返回新线程句柄,失败返回0
*_stdcall表示:1、参数从右向左压入堆栈
*              2、函数被调用者修改堆栈
*/

stack_size
新线程的堆栈大小,或为0。
arglist
要传递给新线程的参数列表,或者为NULL。
指向SECURITY_ATTRIBUTES结构的安全指针,该结构确定返回的句柄是否可以由子进程继承。如果Security为NULL,则不能继承该句柄。对于Windows 95应用程序,必须为NULL。
initflag
用于控制新线程的初始状态的标志。将initflag设置为0可立即运行,或将CREATE_SUSPENDED设置为处于挂起状态的线程;使用ResumeThread执行线程。将initflag设置为STACK_SIZE_PARAM_IS_A_RESERVATION标志,以使用stack_size作为堆栈的初始保留大小(以字节为单位);如果未指定此标志,则stack_size指定提交大小。
thrdaddr
指向接收线程标识符的32位变量。如果为NULL,则不使用。


返回值

如果成功,每个函数都返回一个新创建线程的句柄;但是,如果新创建的线程退出得太快,_beginthread可能不会返回有效的句柄。如果有错误,_beginthread返回-1L,如果线程太多,errno设置为EAGAIN,如果参数无效或堆栈大小不正确,设置为EINVAL,或者如果资源不足(比如内存),设置为EACCES。当发生错误时,_beginthreadex返回0,设置errno和_doserrno。


创建示例:

...//初始化函数unsgined int _stdcall ThreadFun(PVOID pM)
{//实现代码reuturn 0;
}
int main()
{HANDLE hand;handl = (HANDLE)_beginthreadex(NULL,0,ThreadFun,Null,0,NULL);WaitFOrSingleObject(ThreadFun,INFINTE);//代码实现return 0;
}


可执行文件中的调用C运行时库(CRT)的线程应将_beginthreadex和_endthreadex函数用于线程管理,而不是 CreateThread和 ExitThread;这需要使用CRT的多线程版本。如果使用CreateThread创建的线程调用CRT,则CRT可能会在内存不足的情况下终止进程。

CreateThread()函数及_beginthreadex()函数相关推荐

  1. 采用_beginthread/_beginthreadex函数创建多线程

    1.CRT简介: CRT: (C Runtime Library)即C运行时库,是系统运行的基础,包含了c常用的函数集(如:printf,malloc,strcpy等),为运行main做了初始化环境变 ...

  2. 用Debug函数实现API函数的跟踪

    用Debug函数实现API函数的跟踪 如果我们能自己编写一个类似调试器的功能,这个调试器需要实现我们对于跟踪监视工具的要求,即自动记录输入输出参数,自动让目标进程继续运行.下面我们就来介绍在不知道函数 ...

  3. linux callback函数,C++回调函数(callback)的使用

    什么是回调函数(callback) 模块A有一个函数foo,它向模块B传递foo的地址,然后在B里面发生某种事件(event)时,通过从A里面传递过来的foo的地址调用foo,通知A发生了什么事情,让 ...

  4. c语言callback函数用法,C函数回调(callback)C++类成员函数的方法

    问题的由来 C回调的步骤一般是: 声明callback函数类型: 根据类型定义一个callback函数A: 把定义的函数A,作为参数传入到另外一个函数B: 函数B会在某个时刻,调用A. 因为C里面函数 ...

  5. render函数和redirect函数的区别+反向解析

    render函数和redirect函数的区别+反向解析 1.视图函数:一定是要包含两个对象的(render源码里面有HttpResponse对象)   request对象:----->所有的请求 ...

  6. Python day10 global关键字、函数递归、匿名函数、map函数的用法详解

    1.global关键字 引用全局变量,在局部全局变量改变,也会改变,global相当于指针,将地址指向全局变量的name name='littlepage'def littepage():global ...

  7. C++ 笔记(13)— 函数(函数声明、函数定义、函数调用[传值、指针、引用]、函数参数默认值、函数重载)

    每个 C++ 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数. 1. 函数声明 函数声明告诉编译器函数的名称.返回类型和参数.函数声明包括以下几个部分: ret ...

  8. Go 学习笔记(16)— 函数(02)[函数签名、有名函数、匿名函数、调用匿名函数、匿名函数赋值给变量、匿名函数做回调函数]

    1. 函数签名 函数类型也叫做函数签名,可以使用 fmt.Printf("%T") 格式化参数打印函数类型. package mainimport "fmt"f ...

  9. Go 学习笔记(15)— 函数(01)[函数定义、函数特点、多值返回、实参形参、变长参数,函数作为参数调用]

    1. 函数定义 Go 语言最少有个 main() 函数.函数声明告诉了编译器函数的名称,返回类型和参数. func funcName(parameter_list)(result_list) {fun ...

最新文章

  1. Enterprise Vault 系列 [CA和DA]
  2. redis 3.0 集群__数据迁移和伸缩容
  3. mysql date类型加一个月jdbc_JDBC操作数据库Date类型数据
  4. huffman python_Python huffman包_程序模块 - PyPI - Python中文网
  5. 使用Linux进行c或c++编程
  6. ssh框架配置文件流程_通过配置文件和安排增强您的工作流程
  7. Effective C# Item33:限制类型的可见性
  8. Unity实现物体生命值跟踪的方法
  9. Android对话框动态加载布局
  10. 菜单、toast、对话框的使用
  11. Linux下禁止使用swap及防止OOM机制导致进程被kill掉
  12. 查理·芒格:分享12个顶级思维模型
  13. oracle tablespace next参数的理解
  14. ‘gbk‘ codec can‘t decode byte 0xa4 in position 16433: illegal multibyte sequence
  15. 如何TIA博途中更新HSP硬件目录?
  16. 老调重弹-access注入过主机卫
  17. GEE遍历影像中每个像元的值
  18. 高斯,数据科学家最爱的男人(我们不是GAY!)
  19. linux下网页制作,linux网页制作
  20. 【Flink】Specifying keys via field positions is only valid for tuple data types.

热门文章

  1. 动态规划维特比算法c语言实现,viterbi算法实现
  2. 解决windows10和ubuntu双系统切换时Windows时间不对的问题
  3. python讲师金角大王_老男孩-金角大王-python学习博客地址
  4. 脱胎换骨 WinXP优化精湛10招
  5. 一、Tomcat性能优化
  6. 【Java 8 新特性】Java 8 BigDecimal求和
  7. navicat新建数据库的步骤
  8. R语言绘制分类变量柱状图
  9. VueMusic-13歌手列表
  10. 【金三银四】Java集合面试题(2021最新版)