结束一个线程

来源:互联网 发布:人工智能畅销书 编辑:程序博客网 时间:2024/05/27 03:27

正常安全的结束一个进程

线程函数运行完返回

         此种方法是所有线程结束方法中最安全也最推荐的线程结束方法。

         在线程函数返回时,将会执行以下清理工作:

              (1)调用析构函数销毁线程中创建的所有C++对象。

              (2)正确释放线程栈空间。

              (3)将线程的退出代码(在线程的内核对象中维护)设为函数返回值。

              (4)系统递减线程的内核对象的使用计数。

非正常结束一个线程

1. 在本线程中调用API结束线程。

       这里提供两个函数,一个是windows API,一个是C++运行库函数。

       Windous API函数

                           VOID ExitThread(DWORD dwExitCode);

       C++运行库函数

                          void _endthreadex(unsigned retcode);

         这两个函数都可以终止线程的运行,并使得操作系统开始清理该线程使用的所有操作系统资源。但是,你的C++资源(例如对象)不会被清理。

         两个函数的区别在于,_endthreadex还需要清理由_beginthreadex而分配的内容,因此,如果你使用_beginthreadex,那么你一定需要使用_endthredex函数来结束线程。否则,则需要使用ExitThread API。

2. 在另一个线程中调用API结束线程

      BOOL TerminateThread(HANDLE hThread, DWORD dwExitCode);

     TerminateThread函数能杀死任意一个线程,前提是你能提供一个线程的句柄。线程的退出代码将为dwExitCode参数,同时,线程的内核对象使用计数会递减。

      需要注意的几点有:

              1) 与ExitThread不同的是,ExitThread结束一个线程时,线程的栈空间也会被销毁,而使用TerminateThread函数并不销毁线程的栈空间,只能等到拥有此线程的进程终止,该线程栈才会被释放。

              2) 通常,DLL会在线程终止运行时收到通知,不过如果线程是用TerminateThread函数终止的,则不会收到通知,最终导致不能执行正常的清理工作。

              3) TerminateThread函数是异步的,即调用的函数后会立即返回,而且不能保证线程已经被终止。如果要确定线程是否终止,你可以使用WaiForSingleObjet系列函数,并将线程的句柄作为参数传入。

3. 终止进程来结束线程

      当进程终止时,它的所有线程都全部终止,它所使用的全部系统资源都将被清理,包括所有线程的堆栈。类似于我们为所有线程都调用了TerminateThread函数,这意味着一些清理工作将不会执行,例如将数据写回文件。

线程终止运行时,会发生的事情(摘自《WINDOWS核心编程》)

    • 线程拥有的所有用户对象句柄会被释放。在WINDOWS中,大多数对象都是由包含了“创建这些对象的线程”的进程拥有的,但一个线程有两个用户对象:窗口(window)和挂钩(hook)。一个线程终止运行时,系统会自动销毁由线程创建或安装的任何窗口,并卸载由线程创建或安装的任何挂钩。其他对象只有在拥有线程的进程终止时才被销毁。
    • 线程的退出代码从STILL_ACTIVE变成传给ExitThread或TerminateThread的代码。
    • 线程的内核状态变为触发状态。
    • 如果线程是进程中的最后一个活动线程,那么系统认为进程也终止了。
    • 线程内核对象的使用计数递减1。
0 0
原创粉丝点击