线程的结束有两种方式,一种是线程执行完功能函数,自然结束。另一种是被其他线程调用TerminalKernelThread函数强行终止。
其中,第一种结束情况属正常情况,这种方式不会发生资源泄漏等情况,而采用第二种方式,被结束线程申请的系统资源可能得不到释放,从而造成资源的消耗。因此,一般情况下,不建议采用第二种方式结束一个线程。
上文中多次提到,一个新创建的线程刚开始被调度投入运行的时候,是从KernelThreadWrapper函数开始运行的。该函数的上半部分在4.2.4节中有介绍,本节重点关注该函数的下半部分,因为这是线程的结束部分。
下面是该函数的相关代码,为了便于阅读,我们分段解释。
上述代码中,黑体部分调用了线程的功能函数,在线程从功能函数返回的时候并没有结束,而是继续执行以下代码:(www.xing528.com)
执行完功能函数后,该函数首先设置线程核心对象的返回值,以及线程状态(TERMINAL)。
上述代码唤醒所有等待当前核心线程对象的其他线程。核心线程对象本身也是一个同步对象,其他线程可以等待核心线程对象。一旦核心线程对象的状态被设置为TERMINAL,所有等到该对象的其他线程将被激活(类似EVENT对象的SetEvent调用)。上述代码就是用来激活所有等待该核心线程对象的其他线程的,这部分代码的详细含义,请参考4.2.3节。
上述代码把当前线程核心对象插入终止队列(lpTerminalQueue),然后调用ScheduleFromProc函数,引发一个重新调度操作。需要注意的是,此后当前线程由于不会出现在就绪队列,因此永远得不到调度。处于结束队列(lpTerminalQueue)的核心线程对象,在合适的时机会被系统删除。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。