windows核心编程这本书走马观花似的看了看,但是没有看完,最终收获也是几乎没有,今天决定好好看完,然后写点读后感,期待有好的收获。
先从第六章线程开始吧,毕竟这玩意儿像比较牛逼的招式,至于内功心法估计只看这个还是不够的。
一、来说下线程是个啥东西吧,我觉得也是书上说的,线程包含两个东西,一是线程内核对象,二是线程栈。
线程内核对象:实际上线程内核对象就是以个数据结构,线程用这个数据结构来存储自己的一些运行时信息,一遍被切换时可以把运行状态保存下来;操作系统则利用这个数据结 构来管理线程,比如里面有个引用计数字段,为0时,系统kill掉线程,等等。
但是这个数据结构对象存储在哪里呢,是进程地址空间内,还是存储在内核空间里呢,看了点操作系统原理,觉得它的存储取决于系统实现多线程的方式,比如线程是完全在用户态实现的呢,还是完全在内核态实现的呢,还是杂交实现的呢。我认为windows应该是把他存在内核空间了,待找到答案后在来补充吧。
线程栈:线程栈这玩意就是在进程地址空间内为每个线程开辟的不同的栈,用来存放各个调用过程,和每个过程内的参数,local变量,返回地址。
有了这两样东西就相当于,一,系统可以调度管理我了,二,我自己可以执行了,函数调用过程就塞到调用栈就可以啦。
二 、线程终止运行
直接搬书上的过来,有4中方式终止线程
1 线程函数的返回(强烈推荐)
2 线程调用ExitThread自杀(避免此种方法)
3 同一爹内的兄弟线程或另一进程内其他线程调用TerminateThread,别人给判个死刑(避免此种方法)
4 包含线程的进程终止运行(避免此种方法)
此处有点不解,2 3中方法既然windows你不提倡,干嘛提供api呢,待找到答案后在来补充吧。或者有路过的大牛指点一二。
首先来说线程函数的正常返回,这是终止线程最好的方式,也是保证线程所有资源被正确清理的唯一方式。那么有哪些需要清理的呢?
a、线程函数中创建的C++对象能通析构正确销毁
b、操作系统正确释放线程栈使用的内存
c、操作系统把线程的退出代码设为函数返回值
d、系统递减线程内核对象的引用计数(话说上面2 3中发发也可以达到这个目的啊)
其次ExitThread
第三TerminateThread
第四进程终止运行
线程终止运行时都会做哪些呢,不管是老死自杀还是死刑犯,完事之后呢,线程拥有的句柄会被释放,话说不是所有内核对象属于进程嘛,其实有2个是属于线程的,窗口句柄和hook句柄;线程的退出代码会被更新下;线程的内核对象状态变为触发状态,同时引用计数减一;如果是最后一个线程,则老爹也就寿终正寝了。
三 线程的创建
创建线程最好用_beginThreadEx 而不要直接调用系统的CreateThread。为什么呢,这要提到tls(Thread local storage),tls也可以理解为一个DWORD的数组,数组里可以东西,这个tls属于线程。有啥用呢,大致上就是,我一个线程想有一个只属于自己的全局变量,咋搞呢,就用tls吧。关于tls先说这么多吧。其中_beginThreadEx的实现中会初始化这个tls,然后在调用CreateThread创建线程,当线程函数退出时,这里面还会调用相应的_endThreadEx,end里面会delete掉初始化的tls。所以大家在迫不得已要调用ExitThread的时候调用_endThreadEx或许是稍微更好一点的选择。