• TerminateThread()结束一个线程会有什么结果?


    线程的handle用处:

    线程的handle是指向“线程的内核对象”的,而不是指向线程本身.每个内核对象只是内核分配的一个内存块,并且只能由内核访问。该内存块是一种数据结构,它的成员负责维护对象的各种信息(eg: 安全性描述,引用计数等)。

    CloseHandle()

    在CreateThread成功之后会返回一个hThread的handle,且内核对象的计数加1,CloseHandle之后,引用计数减1,当变为0时,系统删除内核对象。

    但是这个handle并不能完全代表这个线程,它仅仅是线程的一个“标识”,系统和用户可以利用它对相应的线程进行必要的操纵。如果在线程成功创建后,不再需要用到这个句柄,就可以在创建成功后,线程退出前直接CloseHandle掉,但这并不会影响到线程的运行。

    不执行CloseHandle() 带来的后果:

    若在线程执行完之后,没有通过CloseHandle()将引用计数减1,在进程执行期间,将会造成内核对象的泄露,相当与句柄泄露,但不同于内存泄露, 这势必会对系统的效率带来一定程度上的负面影响。但是,请记住,当进程结束退出后,系统仍然会自动帮你清理这些资源。但是在这里不推荐这种做法,毕竟不是 一个良好的编程习惯!
    ( 应用程序运行时,有可能泄露内核对象,但是当进程终止运行时,系统能确保所有内容均被正确地清除。另外,这个情况是用于所有对象,资源和内存块,也就是说,当进程终止时,系统将保证不会留下任何对象。)

    TerminateThread()

    函数的声明如下:

    BOOL TerminateThread( HANDLE hThread, DWORD dwExitCode);

    作用:

    在线程外终止一个线程,用于强制终止线程。

    参数说明:

    HANDLE htread:被终止的线程的句柄,为CWinThread指针。

    DWORD dwExitCode:退出码。

    返回值:

    函数执行成功则返回非零值,执行失败返回0。调用getlasterror获得返回的值

    #include <iostream>
    #include <vector>
    #include <utility>
    #include <windows.h>
    DWORD WINAPI  mythread(LPVOID argv)
    {
        while(true)
        {
            char* p = new char[1024];
    
            delete p;
        }
    }
    
    int main(int argc, char **argv)
    {
    HANDLE hThread = CreateThread(NULL, 0, mythread, NULL, 0, NULL);
    
        Sleep(1000);
    
        TerminateThread(hThread , 0);
        hThread = NULL;
    
        char* p = new char[1024]; //这里会死锁,过不去
    
        delete p;
        
        system("pause");
    }

    为什么死锁呢?new操作符用的是小块堆,整个进程在分配和回收内存时,都要用同一把锁如果一个线程在占用该锁时被杀死(即临死前该线程在new或delete操作中),其他线程就无法再使用new或delete了,表现为hang住。

    <核心编程>里明确提醒不要TerminateThread,但原因并不是血淋淋滴。今天发现的这个bug印证了此书的价值。

    TerminateThread终止线程后,堆栈没有被回收!

    当我推出这样的结论时,很快就想到了MSDN上面的说明。以前看到MSDN关于TerminateThread函数的说明,其中提到,TerminateThread结束线程时,不会回收线程的栈!

    对于MSDN中的这句话,我一直当它不存在。因为以往的分析结果,TerminateThread结束线程后,栈资源似乎被回收了,栈变量的析构函数被调用了!如果是这样的话,TerminateThread基本上是安全的!至少,对于线程函数局部变量的声明和回收,是安全的!而new的内存,自然还是需要手动回收的了。

    但是,这次得出的结论,证明MSDN所说属实!

    看来,应该尽量不使用TerminateThread终止线程。

    MSDN 2005 原文:TerminateThread is used to cause a thread to exit. When this occurs, the target thread has no chance to execute any user-mode code and its initial stack is not deallocated. DLLs attached to the thread are not notified that the thread is terminating.

    转:http://hi.baidu.com/whmtorrent/item/cd9d29b31b25f0ef4ec7fd52

  • 相关阅读:
    Android MVP架构分析
    JavaEE基本了解
    学习面试题Day09
    使用反射来实现简单工厂模式
    Android Material Design简单使用
    c语言 找最小值
    c++ 计算指定半径圆的面积
    c++ 字符串拷贝以及合并
    python yaml文件读写
    python 列表元素替换以及删除
  • 原文地址:https://www.cnblogs.com/cheng07045406/p/3224032.html
Copyright © 2020-2023  润新知