当前位置:C++技术网 > 精选软件 > Windows核心编程入门:5 什么是内核对象,什么是用户对象

Windows核心编程入门:5 什么是内核对象,什么是用户对象

更新时间:2016-05-14 23:56:09浏览次数:1+次

    在《Windows核心编程入门3:轻松理解用户态和内核态》中,我已经详细的描述了用户态和内核态的区别。有了这个基础,相信后面的文章理解起来会容易的多。如果你还没有看,一定要先去看哦。
    要理解内核对象和用户对象,我们先搞清楚什么是对象。
    我们学过C++,我们知道C++有对象,这是面向对象思想的一个特点。在面向对象思想中,一切都是对象。所以,我们知道了对象的一些基本特征。对象是思想的一个产物,在计算机中,你是没法找到一个个叫做对象的东西的。在内存中,所有的东西都是内存块。不管你是对象,还是非对象,还是外星人,还是空气,全都是内存块,或者是一个位,或者是一个字节,或者是一大块连续的内存块,或者是多个不连续的内存块形成的一个结构。不管表现为哪样,都是一个吊样,那就是内存块。
    站在编程的角度来讲,我们通常理解的对象一般是面向对象语言的对象。对象是类实例化得到的。所以,提到对象,你可能会想起类。类是一种类型,类实例化实际上就是定义一个变量而已。结构体是类的始祖,类算得上是结构体。我们一般不会在结构体中写成员函数,结构体中只有数据,一般是在C语言的写法。(感谢【卡尔卢】的矫正),矫正原文:【"类继承于结构体,所以结构体也是类"的说法是错误的。一方面类并没有继承结构体,另一方面,即便类继承了结构体,在面向对象的说法中,也只能说类也是结构体,而不能说结构体是类。 "一般在结构体中不写成员函数",这只是编程习惯。结构体与类的区别仅仅是默认访问控制权限的不同,结构体中不写成员函数的做法是c习惯的做法。】附加说明:【我提到的继承,算是思想上的,相当于是借鉴。表达不准确,很感谢卡尔卢指正。至于说结构体和类的关系的说法,就看站在什么角度去看了。我们可以说类是特殊的结构体,因为多了成员函数和访问权限控制,也可以说,结构体是特殊的类,因为少了成员函数和完全的访问权限。哪一种说法都可以。不过继承的表述确实不准确,产生了歧义。欢迎各位指正,相互学习。】
    从内存角度来看,结构体和类都是定义一块内存的组织形式而已。成员函数也不过就是一个函数地址罢了。
    所以,在Windows中,我们提到的对象,很多都是泛化的概念。也就是说,Windows中将结构体定义的对象称为一个对象,但是这个对象和我们C++语言定义的对象是有一些差别的。
    我特别说到这一点,是因为基本上开始学习Windows的人,经常会被对象这个词语迷惑。也不知道以上的解释能不能给你解开疑惑,如果还有疑惑,可以在文章底部留言(C++技术网首发,我会收到邮件提醒,会第一时间回复)。
    知道了Windows中的对象的概念,那我们继续来分辨内核对象和用户对象的含义。
    内核态是系统内核程序运行时的状态,可以无所不能,而用户态程序只能执行普通的指令,访问有限的资源。自然而然,内核对象就是内核空间的对象,用户对象就是用户空间的对象。所谓的空间,也就是内存段。内核所在的内存空间与普通的用户程序所在的内存空间是隔离的,这样可以提高系统的稳定性。我们知道了,两种对象出身的位置不同,也就有了不同的人生经历。
    先来看看用户对象。用户对象也就是我们使用的最多的对象。用户对象在用户空间中,我们的应用程序也是在用户空间中,所以我们一般操作的对象就都是用户对象了。
    用户对象长什么样呢?前面解释了对象,用户对象也就只是用户空间中的各种对象,可以是一个结构体也可以是类对象。如果你高兴,可以将任何变量看成是对象。通常来说,Windows中的对象都是结构体了,因为Windows操作系统是面向过程方式组织的,没有直接的类的关系,所以你看到的API都是一个个的函数,而不是一个个的类成员函数。但是Windows中无处不含有面向对象的思想,所以才有继承关系,对象这些东西。也就是说,这些叫法都是逻辑上的,实际上,并不是像C++那样的类对象。
    用户对象可以是类对象和结构体。那么内核对象呢?内核对象通常是结构体了。内核中的每一个资源,系统都会对其统计和状态维护。比如对进程线程的状态维护。系统需要一个存储状态的数据类型,自然而然,也就用到了结构体。Windows中有大量的结构体,都是这个作用。而这个结构体,本身与资源本身没有直接关系,但是有间接关系。
    或许曾经你总以为,关闭了线程句柄,就认为线程就关闭了。其实是不对的。线程句柄是线程状态结构体的一个成员,这个句柄相当于线程的名字。把一个人的名字删除,这个人不会从世界上消失。而包括句柄在内的其他信息组合在一起,就可以完整的描述线程的状态。系统就通过这个状态结构体来管理线程,比如暂停线程运行、停止线程。
    所以,我们的内核对象,也就是这些结构体变量了。内核对象看似很复杂,看似很神秘,其实就是结构体变量。如此看来,也不是那么牛逼嘛。这就好比富二代表面上牛气哄哄的,实际上他也是一个普通人哦。
    然而就是因为所处的位置不一样,有的人出身就很有地位,有的人出身就很贫贱。内核对象出身在内核空间,处在系统内核的保护之下,自然高人一等。所以内核对象也可以做很多用户对象不能做的事情。比如内核对象可以对线程进行同步,跨进程跨线程同步,用户对象无法做到。为什么会这样呢?
    你想想,进程线程本质上就是对CPU的操作,执行指令。CPU这些东西是硬件,自然也是系统内核管理的东西。内核对象处在内核空间中,正好可以和硬件特性的东西亲近,如进程。甚至要对这些东西管理,就需要特定的内核对象。
    可能这里和你想象中的内核对象有差异。是的,我们通常熟悉的是互斥量、锁之类的,然而这只是冰山一角哦。如果你不是很深入的学习系统内核,很多内核对象你都不知道哦。这些甚至是编写操作系统才会接触的内核对象。我们平时做系统核心编程,关心最多的就是同步等用的一些内核对象了,其实是很少很少的一部分。
    但是我们平时编程,这很少一部分的内核对象也就够了。至于确切的有哪些内核对象,我想Windows核心编程书上会很详细的告诉你的。我这里也就是帮助你全面深入的理解,什么是内核对象和用户对象哦。如果你还有不清楚的地方,记得留言。