线程
其实在一个进程中真正做事情是线程,因此每个进程至少有一个线程。(其实操作系统会为每个进程自动创建一个主线程,这个主线程的执行函数但是我们的Main函数)
操作系统创建线程的时候和创建进程的行为差不多:
1.创建一个线程内核对象,这个内核对象为记录关于线程的一些基本信息。
2.为线程在进程的地址空间中分配一个栈用来保存在线程中所产生的资源。
线程的创建
创建线程的时候可以设置如下信息:
1. 线程栈的大小(一般默认是1MB)
2. 线程执行函数的地址
3. 线程启动参数
线程创建成功能,操作系统会为线程配一个唯一标示的线程ID。
线程的终止
1. 正常的线程终止
当线程的执行函数正常返回后,线程也就算完成了他的使命。算是正常终止了。这个时候操作系统会做如下事情:
(1)销毁在线程函数中产生的所有对象
(2)释放线程栈所占用的内存空间
(3)将线程内核对象的退出代码设为线程函数的返回值。这个时候也会触发线程信号量,让所有等待该线程信号的对象能获得该信号(例如:Thread.Join函数(.NET 类库))
(4)减少线程内核对象的引用计数
2. 非正常的线程终止
在线程执行函数中,线程本身可以随时调用ExitThread来终止自身。或者在线程执行函数中调用TerminateThread来终止其他线程。个人认为这种方式属于非正常的线程终止。
当调用ExitThread时,线程堆栈会被销毁。但是调用TerminateThread时,线程栈则不会被销毁。不过关于线程内核对象的维护,操作系统在线程终止时还是会进行和正常终止时一样的清理工作。
线程深层原理
当创建一个线程时,操作系统并不是直接就去调用我们提供的线程执行函数。而是去调用一个操作系统内部函数RtlUserThreadStart。然后将我们提供的线程执行函数地址以及
启动参数传送给该内部函数。(传递方式是将这两个参数压入线程栈中)。
在该内部函数中,如下活动会被执行:
1.调用线程执行函数
2.捕捉线程执行函数的异常,以及正常返回的信号。(操作系统会对异常进行默认的处理:弹出一个框提示用户,当用户点关闭后终止进程)
3.调用ExitThread终止该线程。
浙公网安备 33010602011771号