内核对象的创建和使用

1、进程内核对象句柄表

2、创建与关闭内核对象

3、进程间内核对象句柄的共享

 

 

1、进程内核对象句柄表

当一个进程初始化时,系统会为它分配一张内核对象句柄表。这个表只用于管理内核对象句柄。GDI和用户对象不会影响到这张表。表中的每一项有4个域。  即句柄ID,对象内存地址,访问屏蔽位,标志位。

 

当一个进程初始化时,句柄表为空。 现在假设你调用CreateFile函数创建一个文件对象,内核首先会查找当前进程中的句柄表,将一个空的表项取出来,并分配一个内核对象,将该对象的地址写入第二个域(即,对象内存地址),然后访问屏蔽设置为完全访问,相应的标志位也会被设置。用于内核对象创建时返回与进程相关的句柄,而这些句柄可以在同一个进程中被其所有线程使用。该句柄是一个非透明值,有可能返回的是句柄表中的索引,也有可能是一个其它的值。但这个句柄的确是可以与这个内核对象相关联。

 

2、创建与关闭内核对象

如果创建内核对象失败,那返回的句柄通常为NULL,但也有可能是INVALID_HANDLE_VALUE,例如CreateFile函数。当查看一个函数的返回值时,应该特别小心。

 

无论你是怎么创建内核对象,都应该调用CloseHandle将其释放。内核会检测这个对象的引用计数,当发现他的引用计数为0的时候,便会将其释放。 并且,如果一个进程中,如果调用了CloseHandle,则这个HANDLE对此进程则会变成无效,而对于其它使用这个内核的进程来说,并没有影响。

 

3、进程间内核对象句柄的共享

当一个进程创建出一个内核对象时,这个对象就与此进程相关联。但是,并不是所有情况都是如此,许多时候,我们需要多个进程之间共享内核对象。共享一个内核对象句柄的方法大概有三种。 1、通过继承共享,2、通过有名内核对象共享。3、通过句柄拷贝共享。

注:共享的是内核对象的句柄,内核对象属于内核,无法共享。

 

通过继承共享则要求共享的进程间是父子关系。 如一个进程中调用CreateFile创建了一个文件对象。如果我们想要这个对象的句柄在这个进程的子进程中被使用。则我们在创建这个对象时,对SECURYTY_ATTRIBUTES结构中的bInheritHande设置为TRUE。 这样这个句柄就能够被子进程共享。 而我们在创建子进程时,需在调用CreateProcess时将其参数bInheritHandles传递为TRUE,标志着他需要继承父进程的句柄。

值得注意的是,继承句柄相当于是对父进程中句柄的拷贝,当一个进程被创建时,如果指定为需要对父进程中的句柄进行继承,则系统会查找其父进程中的句柄表,找到可以继承的句柄,并将其整个表项复制到子进程的句柄表中。内核对象的引用计数相应增加1。 因此,如果一个子进程被创建后。父进程又创建了一个可以继承的对象句柄。但这个句柄不会被子进程继承。

另外一个问题就是,子进程无法知道自己拥有了该句柄的使用权,此时就需要通过一些手法来让子进程知道。最常用的便是通过参数传递。将句柄值通过pCommandLine传递给子进程,子进程解析后使用。也可以通过消息或是环境变量的方式通知。。

 

通过有名对象进行对象句柄共享是最简单的方式,像事件,信号量,互斥变量等都支持有名创建。如创建CreateMutex的时候,只需为其最后一个参数传递一个0结尾的字符串,便可以标志这个变量。需要注意的是,这个名字很有可能冲突,不同种内的内核对象共同使用一个名字池,如果已经有这个名字,并且先前使用此名字的内核对象也是一个Mutex,则当调用GetLastError()时,会返回ERROR_ALREADY_EXISTS。 系统将直接返回其句柄,并将其引用计数加1。否则返回NULL,表示创建失败。

 

由于这个特性,我们可以使用它来强制你的程序只能开一个实例。代码如下

 

 

  1. #include<windows.h>  
  2. #include<tchar.h>  
  3. int  _tmain()     
  4.     
  5. {     
  6.     
  7.        HANDLE hMutex = CreateMutex(NULL,TRUE,”MyMutex”);     
  8.     
  9.        if(GetLastError() == ERROR_ALREADY_EXISTS)     
  10.     
  11.        {     
  12.     
  13.               MessageBox(TEXT(“程序已经有一个实例在执行”),TEXT(“友情提示”),MB_OK);     
  14.               CloseHandle(hMutex);  
  15.     
  16.               return 0;     
  17.         }     
  18.   
  19.     
  20.       
  21.     
  22.        //做你程序应该做的事     
  23.         CloseHandle(hMutex);    
  24.         return 0;     
  25.     
  26. }     
  27.   
  28.   
  29. 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wqjqepr/archive/2010/06/26/5695561.aspx  

 

最后一个共享变量的方式就是采用DuplicateHandle进行拷贝,具体用法参照MSDN即可。

 

对象的句柄是一个非透明的值,在不同的场合,会有不同的句柄与同一个内核对象对应。标志着不同的权限,不同的环境。 因此用到的时候要十分小心。并且应该注意句柄的关闭,以防止运行过程中内在泄漏。同时应该注意句柄值的有效性,不要使用一个已经释放了的句柄值。

作者:码瘾少年·麒麟子 
出处:http://www.cnblogs.com/geniusalex/ 
蛮牛专栏:麒麟子 
简介:09年入行,喜欢游戏和编程,对3D游戏和引擎尤其感兴趣。 
版权声明:本文版权归作者和博客园共有,欢迎转载。转载必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载:http://www.cnblogs.com/geniusalex/archive/2010/06/26/1940488.html

时间: 2024-09-17 04:38:04

内核对象的创建和使用的相关文章

核心编程笔记9——内核对象的线程同步2

"信号量内核对象"用于对资源进行计数. 在信号量内核对象内部,和其他内核对象一样,有一个使用计数,该使用计数表示信号量内核对象被打开的次数. 信号量内核对象中还有两个比较重要的数据,分别表示最大资源数和当前资源数.最大资源数表示能够管理的资源的总数,当前资源数表示目前可以被使用的资源数量.   可以使用CreateSeamphore函数来创建一个信号量内核对象,该函数成功返回句柄,失败返回NULL.

内核对象的安全描述符

当你需要创建.打开和操作各种内核对象的时候,系统要创建和操作若干类型的内核对象,强如存取符号对象.事件对象.文件对象.文件映射对象.I/O完成端口对象.作业对象.信箱对象.互斥对象.管道对象.进程对象.信标对象.线程对象和等待计时器对象等等.这些对象都是通过调用函数来创建的.例如:CreateFileMapping函数可使系统能够创建一个文件映射对象.        每个内核对象只是内核分配的一个内存块. 并且只能由该内核访问.该内存块是一种数据结构,它的尵负责维护该对象的各种信息.有些数据成员

《Windows via C/C++》学习笔记 —— 内核对象的“线程同步”之“等待定时器”

等待定时器(waitable timer)是在某个时间或按规定的时间间隔通知自己的内核对象.可以把它理解为一个定时发送信号的东西. 要创建一个等待定时器内核对象,可以调用函数CreateWaitableTimer.可以为该函数赋予不同的参数来指定一个定时器内核对象的属性. HANDLE CreateWaitableTimer(    PSECURITY_ATTRIBUTES psa,    BOOL bManualReset,    PCTSTR pszName);   该函数第一个参数是安全属

C++内核对象封装单实例启动程序的类_C 语言

复制代码 代码如下: //File Name: Singleton.h#pragma once class Singleton{private:    CString strGUID;    CString strMapFileGUID;     HANDLE m_hSingleton; public:    Singleton();    ~Singleton();public:    void AppStart (const HWND & hWnd) const;}; 复制代码 代码如下:

MFC教程(5)-- MFC对象的创建(1)

MFC对象的创建 前面几章介绍了MFC的核心概念和思想,即介绍了MFC对Windows对象的封装方法和特点:MFC对象的动态创建.序列化:MFC消息映射机制. 现在,考查MFC的应用程序结构体系,即以文档-视为核心的编程模式.学习本章,应该弄清楚以下问题: MFC中诸多MFC对象的关系:应用程序对象,文档对象,边框窗口对象,文档边框窗口对象,视对象,文档模板对象等. MFC对象的创建和销毁:由什么对象创建或销毁什么对象,何时创建,何时销毁? MFC提供了那些接口来支持其编程模式? MFC对象的关

对象的创建和存在时间

从技术角度说,OOP(面向对象程序设计)只是涉及抽象的数据类型.继承以及多形性,但另一些问题也可能显得非常重要.本节将就这些问题进行探讨. 最重要的问题之一是对象的创建及破坏方式.对象需要的数据位于哪儿,如何控制对象的"存在时间"呢?针对这个问题,解决的方案是各异其趣的.C++认为程序的执行效率是最重要的一个问题,所以它允许程序员作出选择.为获得最快的运行速度,存储以及存在时间可在编写程序时决定,只需将对象放置在堆栈(有时也叫作自动或定域变量)或者静态存储区域即可.这样便为存储空间的分

MFC教程(5)-- MFC对象的创建(2)

从这些图中可以看到何时.何处调用了什么消息处理函数和虚拟函数,这些函数用来作了什么事情.必要的话,程序员可以在派生类覆盖它们. 在创建工作完成之后,进行初始化,使用文档对象的数据来更新视和显示窗口. 至此,本节描述了MFC的SDI程序从分析命令行到创建或打开文件的处理过程,文档对象已经动态创建.总结如下: 命令行分析→应用程序的FileNew→文档模板的OpenDocumentFile(NULL)→文档的OnNewDocument 命令行分析→应用程序的FileOPen→文档模板的OpenDoc

内部类对象创建是否依赖外围类对象的创建

问题描述 今天看到<ThinkinginJava>有关于内部类对象的一些特性的总结时遇到一个问题:P205上说:创建内部类对象的时刻不依赖于外围类对象的创建.但是书上也有说内部类对象的创建必须依赖于外围类对象,在拥有外部=围类对象之前是不可以创建内部类对象的.那么,当你在创建内部类对象的时刻之前外部类对象如果没有被创建呢?这句话还成立么? 解决方案 解决方案二:看你是不是静态内部类了解决方案三:静态内部类是嵌套类,我说的是内部类.

viratualbox-安装virtualbox之后,不能打开,出现提示严重错误:com对象无法创建。

问题描述 安装virtualbox之后,不能打开,出现提示严重错误:com对象无法创建. 不会插图片. 错误明细是: RC:E_NOINTERFACE (0x80004002) 电脑系统是win7,原来也装过virtualbox,然后因为新建的虚拟机无法导入于是换了一个版本安装,然后现在连virtualbox也打不开了.网上搜索有说是win7兼容问题,换别的兼容运行还是起不来,求教具体的解决方法,谢谢! 解决方案 系统它有问题吧,跟vb冲突了