注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

写着玩

Bob

 
 
 

日志

 
 
 
 

线程学习(2)线程的实现细节  

2009-07-20 01:35:02|  分类: Win32 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

      关于线程的实现细节,我们这里只讨论两个问题。即线程的内核对象和线程栈以及线程的创建过程。上一章我们提到,线程是由线程内核对象以及线程栈两个部分组成的。系统通过线程的内核对象管理线程。线程栈则维护参数和局部变量。

1. 线程的内核对象和线程栈
         下表很清楚的表明了内核对象和线程栈的内容以及直接的管理。

线程的实现细节 - yolcy - 写着玩

调用了CreateThread之后,系统会创建线程的内核对象。内核对象包括一个上下文(用于恢复现场)。从上图可以看出。SP指向了线程栈的首地址。IP指向了系统提供的一个函数。引用计数是表示当前内核对象的引用次数,当递减到0,内核对象将被删除。挂起计数表示此内核对象被挂起的计数,当减到0时,线程成为可调度状态。刚刚创建的线程退出码都是STILL_ACTIVE。都是没有信号状态。也许你问一个问题:为什么初始引用计数要等于2呢?因为线程创建的时候要返回一个句柄,他拥有了一个计数,另一个计数是被创建的新线程自己拥有的。在线程函数返回时递减。弄清楚了这个我们也就清楚了在线程函数最后返回前是否需要调用_endthread或_endthreadex或调用CloseHandle关闭自己。线程内核对象只有在计数器减到0时才会被系统销毁。销毁之后再调用与线程句柄相关的函数都可能出错。比如CloseHandle,当然如果传入的是伪句柄不一定,但是可能递减了其他线程的计数器。

       线程的内核对象一旦创建完毕,系统就分配用于线程栈的内存。内存是用进程的地址空间分配来的。然后,系统将两个值写入栈的上端。第一个值是传给CreateThread的参数(最后传入线程函数),另一个是线程函数的地址。从上图可以看到,内核对象初始化后,IP指向了一个系统的函数BaseThreadStart而不是用户的线程函数。否则系统就无法在线程函数返回时调用ExitThread函数了。

1. 线程的创建过程

           a.建立线程内核对象
           b.设置内核对象初始值:比如计数器=2等
           c.分配内存给线程栈
           d.初始化线程栈:将线程函数和参数push
           e.初始化上下文内容:比如IP和SP以及其他CPU寄存器
            f. 调用BaseThreadStart函数
            g.调用用户线程函数

 

  评论这张
 
阅读(390)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017