《Windows核心编程》之“线程基础”

  本文主要介绍线程的一些基础知识,包括:线程内核对象、线程的创建和退出、线程的初始化和线程上下文等,可以用下面这张思维导图来总结。

 

一、线程VS进程

 内核对象地址空间
进程进程内核对象进程地址空间
线程线程内核对象线程栈

进程是线程的容器,线程依赖于进程的上下文。  

线程要在某个进程的地址空间内执行代码和处理数据。进程内的所有线程共享进程的地址空间(进程上下文)和进程的句柄表。

 

二、创建线程

一个进程的主线程一般由系统创建,它的入口函数是 main() 或 WinMain() 及其 unicode 版本的函数。 

除“主线程”外的其他线程,都是通过 Windows API 创建的。线程的创建过程如下:  
1. CreateProcess/_beginthreadex 等函数创建线程内核对象
2. 系统从**进程的地址空间**中分配内存给**线程栈**使用。
3. 新线程与负责创建的那个线程在相同的进程上下文中运行。(创建远程线程例外)

Jeffrey 推荐使用 Microsoft C++ 运行时库中的  _beginthreadex 函数来创建线程,而不是 CreateThread 函数。

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

其中的重要参数包括:  
1. Security Descriptor (安全描述符)
2. stack size (线程栈的大小)
3. 线程函数指针(地址)
4. 传递给线程函数的参数(地址)
5. 控制位(CREATE_SUSPENDED or not)
6. 存储线程ID

 

三、线程的内幕

强烈推荐认真阅读“线程的内幕”这一小节,特别是“图6-1 如何创建和初始化一个线程”。  

线程创建和初始化的步骤大致如下:  
1. CreateThread 创建线程内核对象  
2. 系统检测到新的线程内核对象后,在进程地址空间中分配**线程栈**  
3. CPU 加载线程上下文
4. 执行 RtlUserThreadStart
5. RtlUserThreadStart 调用 threadFunction

每个线程都有其自己的一组 CPU 寄存器,称为线程的上下文(context)。上下文反映了当线程上一次执行时,线程的 CPU 寄存器的状态。线程的 CPU 寄存器全部保存在一个 CONTEXT 结构(WinNT.h)中。CONTEXT 结构本身保存在线程内核对象中。  
指令指针寄存器(IP)和栈指针寄存器(SP)是线程上下文中最重要的两个寄存器。记住,线程始终在进程的上下文中运行。  

 

四、将伪句柄转换为真正的句柄

GetCurrentProcess 和 GetCurrentThread 函数返回的都是“伪句柄”,而通过 DuplicateHandle 函数可以将伪句柄转换为真正的句柄。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值