项目工程代码中设计句柄的使用,一时不知句柄是何物,通过查阅自学之后,对句柄及其使用有一个初步的了解。分享出来,算是抛砖引玉吧。

  在阐述句柄之前,先说明一下内核对象。

1 内核对象的概念

  内核对象就是一个内存块,有内核分配,只能由内核访问。

  内存块是一种数据结构,其中的数据成员负责维护该对象的相应信息,这个数据结构以及其中的数据成员只能由内核访问,应用程序是无法访问到的,更别说修改其中的数据成员了。

  如何访问这些内核对象(内存块)呢?

  操作系统为使用者封装了一组API,使用者可以通过这些API访问内核对象(内存块)。比如,创建内核对象(内存块)时,使用者调用API中的创建内核对象函数,由内核创建一个内核对象(分配一块内存)。

  内核对象创建好之后,用一个句柄来标识该内核对象(内存块),这个句柄作为函数值返回。这个句柄就是个整数,32位机句柄就是32bit,64位机句柄就是64bit,同一进程中的任何线程都能使用这个句柄,当需要操作内核对象(内存块)时,通过API将这个句柄传给内核,内核就知道是对哪个内核对象(内存块)进行操作了。

创建内核对象,引出句柄。

2 内核对象的使用计数

  在应用程序中,可能有多个进程,这些进程中的一个或多个可能会访问同一个内核对象。内核对象有使用就会有撤销,那么什么情况下内核会撤销某个内核对象呢。内核的使用计数就派上用场了。使用计数是内核对象这个数据结构的数据成员,通过使用计数就能知道该内核对象被多少个进程使用。开始创建内核对象时,使用计数置为1,之后每多一个不同的进程使用该内核对象,使用计数就自加1.

  无论什么方式创建内核对象,我们都需要调用 ClosseHandle 向系统表明我们已经结束使用对象.就在 CloseHandle 函数返回前,它会清除进程句柄表中对应的记录项 -- 这个句柄现在对我们的进程来说是无效的,不要在试图利用它.换句话说,一旦调用 CloseHandle, 我们的进程就不能访问那个内核对象.

  当进程关闭时,内核自动访问该进程仍然打开的内核对象的使用计数,该进程关联的每个内核对象的使用计数自减1,当使用计数减到0时,内核就会撤销该内核对象。

  内核对象的使用计数有些像智能指针。

3 句柄

  内核对象创建好之后,用一个句柄来标识该内核对象(内存块),这个句柄作为函数值返回。这个句柄就是个整数,32位机句柄就是32bit,64位机句柄就是64bit。

  在同一进程中,一个句柄对应一个内核对象,我们在访问内核对象(内存块)时,就是通过句柄告诉内核,我要访问哪个内核对象。

  通俗的说,句柄,就是个编号,操作系统对于我们来说就是个黑箱,我们通过句柄向操作系统要东西。

4 句柄表

  当一个进程被初始化时,系统要为它分配一个句柄表.该句柄表只用于内核对象,不用于用户对象或GDI对象.句柄表也是由内核操作。进程表包含的元素如下所示:

索引  内核对象  内存块的指针访问屏蔽(标志位的DWORD)  标志(标志位的DWORD)

  进程被初次初始化时,句柄表是空的。

  当进程中的线程创建内核对象时,内核给该对象分配一块内存,并对其初始化。内核遍历该进程的句柄表,找出一个空闲位置,设置内核对象,内存块指针,访问掩码,标识,并获取该位置的索引,作为函数值返回,这个索引就是我们所说的句柄。这个句柄只能有同一个进程的所有线程使用, 系统用索引来表示内核对象的信息保存在进程句柄表中的具体位置。其他进程不能使用该进程的索引,因为句柄表不同(每个进程有一个单独的句柄表)。

  所以,句柄实际上是句柄表的索引。可以这么理解,指针指向一块内存空间,那么句柄就是指向其对应的内核对象,通过操作系统提供的API吧句柄传给内核,内核就知道要操作那个内核对象。

内核对象&句柄的更多相关文章

  1. windows内核对象句柄

    内核对象用于管理进程.线程和文件等诸多种类的大量资源,每一个内核对象都只是一个句内存快,它由操作系统内核分配,并只能右操作系统内核访问.这个内存块是一个数据结构,其维护着与对象相关的信息,其中少数成员 ...

  2. Windows进程的内核对象句柄表

    当一个进程被初始化时,系统要为它分配一个句柄表.该句柄表只用于内核对象 ,不用于用户对象或GDI对象. 创建内核对象 当进程初次被初始化时,它的句柄表是空的.然后,当进程中的线程调用创建内核对象的函数 ...

  3. 内核对象&句柄&泄漏&检测

    今天看到这个问题如何评价王垠的 <讨厌的 C# IDisposable 接口>? - 王垠(人物),答案被歪到windows 内核对象和句柄,答案中谈的太浅显而且有误.翻出陈年老文章(此文 ...

  4. 内存块是一种数据结构,内核对象&句柄

    内核对象&句柄 目录 1 内核对象的概念 2 内核对象的使用计数 3 句柄 4 句柄表   项目工程代码中设计句柄的使用,一时不知句柄是何物,通过查阅自学之后,对句柄及其使用有一个初步的了解. ...

  5. 【Windows 操作系统】Windows 进程的内核对象句柄表

    总结: 1.句柄就是进程句柄表中的索引.2.句柄是对进程范围内一个内核对象地址的引用,一个进程的句柄传给另一个进程是无效的.一个内核对象可用有多个句柄.Windows之所以要设立句柄,根本上源于内存管 ...

  6. 【Windows 操作系统】 内核对象|句柄

    内核对象简介 内核对象就是 一些数据结构该结构用来描述存储内核中的一个内存块中的数据信息.   内存块是一种数据结构,其中的数据成员负责维护该对象的相应信息,这个数据结构以及其中的数据成员只能由内核访 ...

  7. windows核心编程---第三章 内核对象及句柄本质

      本章讨论的是相对抽象的概念,不涉及任何具体的内核对象的细节而是讨论所有内核对象的共有特性. 首先让我们来了解一下什么是内核对象.内核对象通过API来创建,每个内核对象是一个数据结构,它对应一块内存 ...

  8. 《windows核心编程系列》三谈谈内核对象及句柄的本质

    内核对象 本章讨论的是相对抽象的概念,不涉及任何具体的内核对象的细节而是讨论所有内核对象的共有特性. 首先让我们来了解一下什么是内核对象.内核对象通过API来创建,每个内核对象是一个数据结构,它对应一 ...

  9. 第9章 用内核对象进行线程同步(1)_事件对象(Event)

    9.1 等待函数 (1)WaitForSingleObject(hObject,dwMilliseonds); ①dwMilliseconds为INFINITE时表示无限等待 ②dwMilliseco ...

随机推荐

  1. 使用Cython时遇到的cl.exe的问题

    最近使用cython时,遇到一个问题,报错如下: cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD "-Id:\program files\python3 ...

  2. c#,绝对值

    Console.WriteLine("输入任意整数"); var n = int.Parse(Console.ReadLine()); var num = Math.Abs(n); ...

  3. 利用Python进行数据分析_Pandas_汇总和计算描述统计

    申明:本系列文章是自己在学习<利用Python进行数据分析>这本书的过程中,为了方便后期自己巩固知识而整理. In [1]: import numpy as np In [2]: impo ...

  4. MongoDB 关系运算符及统计个数及跳过分页

    大于 ($gt).大于等于 ($gte ).小于 ($lt).大于等于 ($lte).等于($eq) 查询价格小于100的商品 db.product1.find({price:{$lt:100}}) ...

  5. go 函数定义

    -------------------------------------------- package main import "fmt" func add(x int, y i ...

  6. Http 与 Https区别

    传统Http协议弊端 传统Http协议弊端是明文的,如果别人采用抓包分析可以获取到明文数据. 什么是Https协议 HTTPS(Hyper Text Transfer Protocol over Se ...

  7. PAT-1003 Emergency (25 分) 最短路最大点权+求相同cost最短路的数量

    As an emergency rescue team leader of a city, you are given a special map of your country. The map s ...

  8. hdu 4496 其实还是并查集

    Problem Description Luxer is a really bad guy. He destroys everything he met. One day Luxer went to ...

  9. (十六)客户端验证与struts2中的服务器端验证

    一.客户端验证: 即用javaScript来验证. <%@ page language="java" contentType="text/html; charset ...

  10. (十一)mybatis之整合ehcache缓存

    一.二级缓存 大家都知道使用mybatis就要先获取sqlsessionfactory,继而使用sqlsession来和数据库交互,每次只需要使用sqlsession对象提供的方法就好,当我们需要第一 ...