精华内容
下载资源
问答
  • 线程句柄
    2021-02-28 07:37:25

    今天温习很久前写的代码,发现自己写的这么一句代码,

    m_hTheard = CreateThread(NULL,0,RegNotifyProc,LPVOID(this),0,NULL);

    CloseHandle(m_hTheard);

    突然给糊涂了,刚创建的线程,为什么有close了,还是当初入门不踏实,没有细想,现在反过来都记不得了,通过查资料,解决了我的疑惑。

    1,线程和线程句柄(Handle)不同,线程是一个程序的工作流程,线程句柄是一个内核对象。线程的生命周期就是线程函数从开始执行到线程结束,线程句柄一旦CreateThread返回,如果你不用它操作线程或者等待线程等操作比如waitforsingleobject,就可以CloseHandle。

    (ps:对于线程来讲,如果线程在运行状态则为无信号状态,在退出后为有信号状态。所以我们可以使用 WaitForSingleObject 来等待线程退出)

    2,CreateThread以后需要对这个线程做一些操作,比如改变优先级,被其他线程等待,强制TermateThread等,就要保存这个句柄,使用完了再操作CloseHandle。

    3、CloseHandle只是关闭了一个线程句柄对象,表示我不再使用该句柄,即不对这个句柄对应的线程做任何干预了,和结束线程没有一点关系。若在线程执行完之后,没有调用CloseHandle,在进程执行期间,将会造成内核对象的泄露,相当于句柄泄露,但不同于内存泄露,这势必会对系统的效率带来一定程度上的负面影响。但当进程结束退出后,系统会自动清理这些资源。

    4、关闭一个内核对象。其中包括文件、文件映射、进程、线程、安全和同步对象等。在CreateThread成功之后会返回一个hThread的handle,且内核对象的计数加1,CloseHandle之后,引用计数减1,当变为0时,系统删除内核对象。

    做一些总结,以作知识积累。

    更多相关内容
  • 易语言取窗口进程线程句柄等源码,取窗口进程线程句柄等,根据进程名取窗口句柄,根据窗口句柄取进程名,取进程线程标识符_,打开进程_,寻找顶级窗口_,关闭内核对象_,创建系统进程快照,取快照中第一个进程信息,取快照中下...
  • 在本文中小编给大家分享了关于易语言关闭多线程句柄方法以及实例内容,需要的朋友们参考下。
  • 易语言取窗口进程线程句柄等源码。@易语言源码分享站。
  • 易语言源码易语言取窗口进程线程句柄等源码.rar
  • 易语言取窗口进程线程句柄等源码
  • 线程ID与线程句柄有啥不同

    千次阅读 2020-06-24 09:44:12
    线程句柄与线程ID的区别: ●CreateThread() API 用于创建线程。 API 返回同时线程句柄和线程标识符 (ID)。 线程句柄有完全访问权创建线程对象。 运行线程时线程 ID 唯一标识线程在系统级别。 ●ID是在Windows系统...

    当某个程序创建一个线程后,会产生一个线程的句柄,线程的句柄主要用来控制整个线程的运行,例如停止、挂起或设置线程的优先级等操作。

    线程句柄与线程ID的区别:

    ●CreateThread() API 用于创建线程。 API 返回同时线程句柄和线程标识符 (ID)。 线程句柄有完全访问权创建线程对象。 运行线程时线程 ID 唯一标识线程在系统级别。
    ●ID是在Windows系统范围内唯一标示Thread的。
    ●Handle是用来操作Thread的,可以有多个,每个HANDLE可以有不同的操作权限,在不同进程OpenThread得到的值不一样。
    ●线程的ID是系统全局的,其HANDLE是进程局部的.

    ●此ID只在线程的生存期内有效。

    ●HANDLE是os和client之间用来操作进程和线程一个桥梁,os有一张维护HANDLE的表单,里面大概放置了 HANDLE的引用计数和有关的属性,HANDLE是os标识进程和线程的东西,但是用户也可以用这个来标识进程和线程,对其操作;而ID是os用来标识进程和线程的,并且是全局唯一的, 但用户可以通过这个ID获得进程线程的HANDLE,多次得到的HANDLE并不一定是一样的.HANDLE是内核对象,而ID好像不是,并没有专门创建ID的函数.

    ●ID是CreateThread时操作系统自动生成的。

    ●线程的句柄和id是不同的。
    在windows系统中,线程的id是唯一对应的,也就是说,如果两个线程返回相同的id,则他们必然是同一线程,反之一定是不同的线程。而线程的句柄并不是线程的唯一标识,线程的句柄只是用来访问该线程的的一个32位值,尽管相同的句柄一定标识同一线程,但同一线程可能拥有两个打开的句柄,因此,不能用句柄来区分两个线程是否是同一线程。

    什么是句柄:

    句柄是一种指向指针的指针。我们知道,所谓指针是一种内存地址。应用程序启动后,组成这个程序的各对象是住留在内存的。如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址访问对象。但是,如果您真的这样认为,那么您就大错特错了。我们知道,Windows是一个以虚拟内存为基础的操作系统。在这种系统环境下,Windows内存管理器经常在内存中来回移动对象,依此来满足各种应用程序的内存需要。对象被移动意味着它的地址变化了。如果地址总是如此变化,我们该到哪里去找该对象呢?
    为了解决这个问题,Windows操作系统为各应用程序腾出一些内存储地址,用来专门登记各应用对象在内存中的地址变化,而这个地址(存储单元的位置)本身是不变的。Windows内存管理器在移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来保存。这样我们只需记住这个句柄地址就可以间接地知道对象具体在内存中的哪个位置。这个地址是在对象装载(Load)时由系统分配给的,当系统卸载时(Unload)又释放给系统。
    句柄地址(稳定)→记载着对象在内存中的地址→对象在内存中的地址(不稳定)→实际对象

    线程与线程句柄的关系:

    句柄可以认为是系统对资源(如线程)的分配的一个编号。关闭这个编号,对于不同的资源,效果不尽相同。对于线程来说,关闭这个编号并不意味着终止线程,只是之后很难再操纵这个线程。

    原文:线程ID与线程句柄区别

    展开全文
  • c++ -- 线程与线程句柄

    2020-02-15 17:05:31
    1,线程和线程句柄(Handle)不同,线程是一个程序的工作流程,线程句柄是一个内核对象。线程的生命周期就是线程函数从开始执行到线程结束,线程句柄一旦CreateThread返回,如果你不用它操作线程或者等待线程等操作...
    转自作者:菜de园子

    链接:https://www.cnblogs.com/candycaicai/archive/2011/02/23/1962554.html;


    今天温习很久前写的代码,发现自己写的这么一句代码,

    m_hTheard = CreateThread(NULL,0,RegNotifyProc,LPVOID(this),0,NULL);
    CloseHandle(m_hTheard);

    突然给糊涂了,刚创建的线程,为什么有close了,还是当初入门不踏实,没有细想,现在反过来都记不得了,通过查资料,解决了我的疑惑。

    1,线程和线程句柄(Handle)不同,线程是一个程序的工作流程,线程句柄是一个内核对象。线程的生命周期就是线程函数从开始执行到线程结束,线程句柄一旦CreateThread返回,如果你不用它操作线程或者等待线程等操作比如waitforsingleobject,就可以CloseHandle。

    (ps:对于线程来讲,如果线程在运行状态则为无信号状态,在退出后为有信号状态。所以我们可以使用 WaitForSingleObject 来等待线程退出)

    2,CreateThread以后需要对这个线程做一些操作,比如改变优先级,被其他线程等待,强制TermateThread等,就要保存这个句柄,使用完了再操作CloseHandle。

    3、CloseHandle只是关闭了一个线程句柄对象,表示我不再使用该句柄,即不对这个句柄对应的线程做任何干预了,和结束线程没有一点关系。若在线程执行完之后,没有调用CloseHandle,在进程执行期间,将会造成内核对象的泄露,相当于句柄泄露,但不同于内存泄露,这势必会对系统的效率带来一定程度上的负面影响。但当进程结束退出后,系统会自动清理这些资源。

    4、关闭一个内核对象。其中包括文件、文件映射、进程、线程、安全和同步对象等。在CreateThread成功之后会返回一个hThread的handle,且内核对象的计数加1,CloseHandle之后,引用计数减1,当变为0时,系统删除内核对象。

    做一些总结,以作知识积累。

    展开全文
  • 关闭线程句柄CloseHandle()

    千次阅读 2020-07-01 11:47:12
    昨天在看老工程中的代码的时候,发现其中创建了一个线程后,并没有通过CloseHandle函数来关闭该句柄。抱着怀疑的态度,就查了些相关的资料,现把自己的调查结果总结如下。 1、创建线程 可以通过调用CreateThread...

    自制工具   翰华Box:https://hanhuabox.lanzous.com/b00zjq9uf

    翰华Box - 开发日志:https://blog.csdn.net/qq_41517936/article/details/106409456

    内核对象&句柄&泄漏&检测:https://blog.csdn.net/qq_41517936/article/details/107060344

    关于线程句柄个人总结:(此处为易语言,其他语言需看各自的函数说明)

    启动线程(欲执行的子程序,参数数据,线程句柄),参数<3>的名称为“线程句柄”,类型为“整数型(int)”,可以被省略,提供参数数据时只能提供变量如果提供了本参数,将向参数变量写入线程句柄(Windows下为HANDLE,Linux下为pthread_t),请在适当的时机关闭该句柄如果不提供本参数接收线程句柄,内部将自动处理线程句柄。

    1.不填写参数3(线程句柄),那么线程在执行完毕后会自动关闭句柄!
    2.填写参数3
    那么当线程执行完毕 强制结束 ,必须手动关闭句柄,否则会有句柄泄漏的可能!(不手动关闭句柄的话,线程内核对象依然存在(具体看下文),当达到一定数量时,句柄泄漏程序崩溃)

    看需求是否需要线程句柄,如果线程有时候需要强制结束,那么肯定要填了,否则不需要!

    ---------------------------------

    昨天在看老工程中的代码的时候,发现其中创建了一个线程后,并没有通过CloseHandle函数来关闭该句柄。抱着怀疑的态度,就查了些相关的资料,现把自己的调查结果总结如下。

    1、创建线程

    可以通过调用CreateThread函数来创建一个线程,函数原型如下:

    HANDLE CreateThread(
      LPSECURITY_ATTRIBUTES lpsa, //线程安全属性
      DWORD cbStack,  //堆栈大小
      LPTHREAD_START_ROUTINE lpStartAddr, //线程函数
      LPVOID lpvThreadParam, //线程参数
      DWORD fdwCreate, //线程创建属性
      LPDWORD lpIDThread  //线程ID
    ); 

    此乃Windows API,MSDN中有详细介绍,在此就不细说了。就说明两点:
    一是参数lpStartAddr,这是线程开始的地址,也就是新创建的线程开始执行的地方,一般将一个函数(线程函数)的地址传递给该参数。
    二是参数lpvThreadParam,这是传递给一中所说的线程函数的参数。

    调用CreateThread时,系统会创建一个线程内核对象,函数CreateThread返回的句柄,可以看作是线程内核对象的一个地址,通过该句柄,你可以操作该线程对象。线程对象的默认引用计数为2,一个是句柄,另一个是线程本身

    2、线程函数

    线程函数的类型并无限制,返回值可以是任意类型,自己定义的类型也可以。参数也无限制,你甚至可以定义多个参数。不过,由于创建线程的时候,只传入了一个LPVOID类型的参数,所以,定义的线程函数最好也只包含一个LPVOID类型的参数,如果需要多个参数,可以传递一个结构体指针,然后强制转换。

    3、结束线程

    结束线程共有四中方法,线程函数返回、ExitThread函数、TerminateThread函数、在进程终止运行时撤消线程。方法间的差别在《Windows核心编程》中有详细介绍,我在此就不重复了。在此,我只说明其中要注意的地方。

    最好结束线程的方法就是通过线程函数返回,这样可以释放掉所有的资源,包括系统资源以及C++资源。可以通过函数返回值来设置线程退出码(Exit Code)。

    可以在线程函数中调用ExitThread函数来结束自己,其参数为线程退出码(Exit Code)。通过ExitThread函数结束线程时,可以释放系统资源,但是不能释放C++资源,如:若在线程函数中定义了一个类的对象,若通过ExitThread函数结束线程,则不会调用该对象的析构函数,需要在其析构函数中释放的资源将不能被释放。

    通过TerminateThread函数,可以强制结束一个线程,其中第一个参数是线程句柄,第二个参数是线程退出码(Exit Code)。通过ExitThread函数结束线程,线程的栈将被销毁,而通过TerminateThread函数结束线程,线程的栈将不被销毁,因为线程是被强制结束的,系统认为可能有其他线程还会使用到该线程的资源。

    4、线程内核对象的销毁

    当线程内核对象的引用计数为0时,系统将销毁线程内核对象。也就是说,线程内核对象的销毁必须满足两个条件:
    一是线程所有的句柄都被close掉(通过函数CloseHandle)。
    二是线程必须已经被结束。

    若线程正在运行,此时,虽然通过CloseHandle关闭了所有与线程相关的句柄,线程内核对象仍然不会被销毁,只有等线程结束时,线程内核对象才会被销毁。

    若未通过CloseHandle关闭线程句柄,虽然线程结束了,线程内核对象仍然不会被销毁。
    调用CloseHandle,将会释放Handle占用的资源,同时将线程内核对象的引用计数减一。
    结束线程的运行,也会将线程内核对象的引用计数减一。

    下面是我的测试代码,在windows xp下,通过vs 2005创建一个win32的控制台程序。
    通过测试发现,如果标记1的代码被注释掉,通过任务管理器查看(选择进程选项卡,查看->选择列,选中“句柄计数”),发现句柄数比正常要多一个,也就是说线程句柄没有被释放,自然,线程内核对象也没办法在进程退出前被销毁。
    若标记2的代码未被注释掉,则类TestClass的析构函数将不会被执行。

    原文:https://www.it610.com/article/4023670.htm

    // ThreadTest_Win32.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include <windows.h>
    
    char QUIT_EVENT_NAME[] = "Quit Event";
    
    void MainFunction( void );
    int SubThreadFunction( void *pContext );
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
     printf( "Entry Main/n");
    
     MainFunction();
    
     printf( "Exit Main/n");
    
     return 0;
    }
    
    void MainFunction()
    {
     // Create thread
     HANDLE hSubThread = ::CreateThread(NULL, 0, ( LPTHREAD_START_ROUTINE )SubThreadFunction, NULL, 0, NULL);
    
     if ( NULL == hSubThread ) {
      return;
     }
    
     // Create quit event
     HANDLE hQuitEvent = ::CreateEvent( 0, FALSE, FALSE, (LPCWSTR)QUIT_EVENT_NAME );
    
     if ( NULL == hQuitEvent ){
      ::CloseHandle( hSubThread ); //Should call CloseHandle to close Handle. 标记1
      return;
     }
    
     for ( INT i = 0; i < 10; ++i ) {
      printf( "Main Thread/n" );
      Sleep( 1000 );
     }
    
     ::SetEvent( hQuitEvent );
     ::CloseHandle( hQuitEvent );
    
     ::CloseHandle( hSubThread ); //Should call CloseHandle to close Handle. 标记1
    
     return;
    }
    
    class TestClass
    {
    public:
    
     TestClass()
     {
      printf( "TestClass:Constructor/n" );
     }
    
     ~TestClass()
     {
      printf( "TestClass:Distructor/n" );
     }
    };
    
    int SubThreadFunction( PVOID pContext )
    {
     TestClass object;
    
     // Create quit event
     HANDLE hQuitEvent = ::CreateEvent( 0, FALSE, FALSE, (LPCWSTR)QUIT_EVENT_NAME );
    
     if ( NULL == hQuitEvent ){
      return 1;
     }
    
     // Wait for quit
     while( TRUE ) {
      printf( "Sub Thread/n" );
    
      DWORD dwWaitResult = ::WaitForSingleObject( hQuitEvent, 1000 );
    
      if ( WAIT_OBJECT_0 == dwWaitResult ) {
       ::CloseHandle(hQuitEvent);
    //   ::ExitThread( 0 ); // If use ExitThread to end the thread, the distructor of TestClass will not be called. 标记2
       return 100;
      }
     }
    }

    内核对象&句柄&泄漏&检测:https://blog.csdn.net/qq_41517936/article/details/107060344

    展开全文
  • Windows中的线程ID和线程句柄 1.什么是句柄? 本质是指针,在Win中句柄是指向指针的指针 typedef void *HANDLE; 一个应用程序,组成该程序的众多对象存在内存中 一般的理解是,只要获取了对象的内存地址便可以...
  • 线程句柄有什么用?

    千次阅读 2019-10-08 14:39:23
    欣赏一下,如何使用线程句柄 HANDLE hThread = CreateThread(NULL, 0, ThreadFunc, this, 0, NULL); if (hThread) { CloseHandle(hThread); } 问题:线程句柄有什么用? 1 线程句柄是内核对象。线程,是工作...
  • 怎样利用多线程句柄设置鼠标忙碌状态呢?下面小编就为大家介绍一下具体的实现方法吧!需要的朋友可以过来参考下
  • 进程线程 句柄

    2015-01-25 21:36:26
    进程线程
  • 线程句柄调试

    2012-11-24 08:11:51
    在控制台创建两个线程以后,此时任务管理器出现3个线程(一个主线程+2个子线程)...线程1退出后,关闭线程1句柄 线程2退出后,不关闭线程2句柄 手动关闭线程2句柄。 任务管理器中将看到: 线程数递减,句柄数也依次减少。
  • 首先在开始正文之前先介绍最简单的获取进程/线程句柄方法。那就是可以在创建进程/线程时获取句柄。创建进程/线程是获取句柄。//进程创建函数BOOL CreateProcess(PCTSTR pszApplicationName,PTSTR pszCommandLine,...
  • 线程句柄HANDLE与线程ID的关系

    千次阅读 2019-04-29 17:39:57
    什么是句柄 句柄是一种指向指针的指针。我们知道,所谓指针是一种内存地址。应用程序启动后,组成这个程序的各对象是住留在内存的。如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址...
  • 1,线程和线程句柄(Handle)不是一个东西,线程是在cpu上运行的.....(说不清楚了),线程句柄是一个内核对象。我们可以通过句柄来操作线程,但是线程的生命周期和线程句柄的生命周期不一样的。线程的生命周期就是...
  • 线程 与 线程句柄 (refer to: http://blog.csdn.net/titan_koa/article/details/2439027) 1. 线程和线程句柄(Handle)不是一个东西,线程是在cpu上运行的.....(说不清楚了),线程句柄是一个内核对象。我们...
  • 主线程只要拥有线程句柄,事后就可以对线程执行某些操作,比如查询线程状态等等,靠的就是句柄,如果没有句柄,系统就无从知道要查的是那个线程的状态。但保持这个句柄不关闭,并不是线程运行的条件。  关闭线程...
  • #include <tlhelp32.h> int GetProcessThreadList(DWORD th32ProcessID) //进程bai的duID { HANDLE hThreadSnap; THREADENTRY32 th32; hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, th32...
  • 什么是句柄:  句柄是一种指向指针的指针。我们知道,所谓指针是一种内存地址。应用程序启动后,组成这个程序的各对象是住留在内存的。如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个...
  • 进程标示取窗口句柄,EnumWindowsProc,取祖宗,GetWindowThreadProcessId,EnumWindows,进程快照,进程获取线程,枚举窗口过程,按窗口句柄取进程信息,取文件名,按进程名获取窗口信息,创建快照,第一个进程,下一个进程,获得...
  • 获取线程句柄的三种方法

    千次阅读 2016-12-19 18:52:58
    获取线程句柄的三种方法 1.通过进程的PID并调用API函数:HANDLE OpenProcess( DWORD dwDesiredAccess, // access flag BOOL bInheritHandle, // handle inheritance option DWORD dwProcessId //
  • 线程ID与线程句柄的关系

    千次阅读 2015-05-20 10:13:08
    很多人不了解线程ID的作用,现进行一定的解释,如有疑问可以留言。本文区分了线程ID 与线程句柄的作用,详细区别可以参考响应的操作系统方面的知识以及MFC相关的知识。
  • • 4、线程句柄 • 5、线程ID • 6、易语言SHCreateThread 511遇见易语言多线程大漠多线程 SHCreateThread function | Microsoft Docs ...
  • Windows线程和线程句柄

    2014-11-17 20:17:09
    原文地址:http://blog.csdn.net/lhsxsh/article/details/3905505...线程的运行和线程句柄之间没有什么关系,线程句柄只是系统提供了一种操作线程的途径。因此,如果接下来不需要使用线程句柄对线程进行操作,最好在...
  • 1,线程和线程句柄(Handle)不同,线程是一个程序的工作流程,线程句柄是一个内核对象。线程的生命周期就是线程函数从开始执行到线程结束,线程句柄一旦CreateThread返回,如果你不用它操作线程或者等待线程等操作...
  • 进程和线程句柄和ID之间转换函数

    千次阅读 2016-09-16 22:08:07
    //获取当前进程句柄 ...//获取当前线程句柄 HANDLE GetCurrentThread(VOID); //获取当前进程ID DWORD GetCurrentProcessId(VOID); //获取当前线程ID DWORD GetCurrentThreadId(VOID); //根据进程ID

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 153,354
精华内容 61,341
关键字:

线程句柄