最近在学习Windows底层原理,准备写个系列文章分享给大家,Michael Li(微软实习期间的Mentor,为人超好)在知乎回答过一些关于学习Windows原理的书籍推荐,大家可以拜读其中一本来入门。我是先从《Windows核心编程》开始了解一些Windows底层管理与硬件交互的原理,然后买了一套冬瓜哥撰写的《大话计算机》系列丛书,学有余力的童鞋强烈推荐你去看看,这套书对计算机整体的运作原理讲解的很系统,涉及了计算机组成原理、网络原理、编译原理、操作系统、硬件等,可以作为不错的入门教材。

Windows核心编程(第5版)电子书及配套代码

学习前需要理解一些系统专业词汇的概念,比如:系统资源、内存管理、句柄、内核态/用户态、Hook、事件、消息处理机制等。不然后续对Windows底层原理的理解会有些误差和盲区,例如很容易将系统资源和CPU资源(CPU使用率)相混淆。

我们将Linux、Unix、Windows对其内核进行对比学习Windows的内核管理机制。参考

Linux:

Linux 优先使用物理内存,当物理内存还有空闲时,linux是不会释放内存的,即时占用内存的程序已经被关闭了(这部分内存就用来做缓存了)。也就是说,即时你 有很大的内存,用过一段时间后,也会被占满。这样做的好处是,启动那些刚开启过的程序、或是读取刚存取过得数据会比较快,对于服务器很有好处。

Windows:

windows则总是给内存留下一定的空闲空间,即时内存有空闲也会让程序使用一些虚拟内存,这样做的好处是,启动新的程序比较快,直接分给它些空闲内存就可以了,而linux下呢?由于内存经常处于全部被使用的状态,则要先清理出一块内存,再分配给新的程序使用,因此,新程序的启动会慢一些。

Windows是由C语言编写的,但是整个系统是面向对象设计的,所以引入了句柄这种数据结构。句柄是一种指向指针的指针,确切点说句柄是一种指向结构体的指针,而指针就是一串内存地址。

Windows是基于事件驱动机制的,整个系统都是通过消息传递来实现的。

Issue:

各大系统平台的程序是用什么机制来接收用户的事件而做出反应的?

Windows的消息系统是如何支持带有图形用户界面的应用程序?

点击鼠标,触发一个系统事件(事件本质上是对消息的封装)——>Windows把这个事件翻译为消息,然后把它放到消息队列中,传递给应用程序——>应用程序从消息队列中接收到这个消息,把它存放在TMsg记录中——>应用程序把消息传递给一个适当的窗口的窗口过程(回调函数)——>窗口过程响应这个消息并进行处理

Windows操作系统消息包括:标准Windows消息(WM_打头) + 通知消息(针对标注Windows控件) + 自定义消息(编程)

消息系统(内核控制中心)组成:消息队列 + 消息循环 + 窗口过程

在Windows中发生的一切都可以用消息来表示,消息用于告诉操作系统发生了什么,所有的Windows应用程序都是消息驱动的。消息本身是作为一个记录传递给应用程序的,这个记录(一般在 C/C++/汇编 中称为“结构体”)中包含了消息的类型以及其他信息。例如,对单击鼠标所产生的消息来说,这个记录(结构体)中包含了单击鼠标的消息号(WM_LBUTTONDOWN)、单击鼠标时的坐标(由X,Y值连接而成的一个32位整数)。这个记录类型叫做TMsg。

在C语言中消息的定义:

typedef struct Msg
{
HWND hwnd; / /窗口句柄
UINT message; / /消息常量标识符
WPARAM wParam; // 32位消息的特定附加信息
LPARAM lParam; // 32位消息的特定附加信息
DWORD time; / /消息创建时的时间
TPoint pt; / /消息创建时的鼠标位置
} TMsg;
typedef struct TPoint
{
int x;
int y;
}TPoint;

不是每个控件都能接收消息,转发消息和绘制自身,只有具有句柄(handle)的控件才能做到。有句柄的控件本质上都是一个窗体(window),它们可以独立存在,可以作为其它控件的容器,而没有句柄的控件,如Label,是不能独立存在的,只能作为窗口控件的子控件,它不能绘制自身,只能依靠父窗体将它绘制来。

然而,并非所有的句柄都是窗体的句柄,Windows系统中还中很多其它类型的句柄,如画布(hdc)句柄,画笔句柄,画刷句柄,应用程序句柄(hInstance)等。这种句柄是不能接收消息的。但不管是哪种句柄,都是系统中对象的唯一标识。本文只讨论窗体句柄。

那为什么句柄使窗口具有了如此独特的特性呢?实际是都是由于消息的原因。由于有了句柄,窗体能够接收消息,也就知道了该什么时候绘制自己,绘制子控件,知道了鼠标在什么时候点击了窗口的哪个部分,从而作出相应的处理。句柄就好像是一个人的身份证,有了它,你就可以从事各种社会活动;否则的话,你要么是一个社会看不到的黑户,要么跟在别人后面,通过别人来证明你的存在。

Windows保存的消息队列是以线程(Thread)来分组的,也就是说每个线程都有自己的消息队列。事件本质上是对消息的封装。


有哪些内核对象:

令牌对象 Token

事件对象 Event

文件对象 File

文件映射对象 Mapping File

线程对象 Thread

时钟对象 Timer

线程池对象 ThreadPool

I/O完成端对象 Completion port

工作对象 Job

邮槽对象 Mailslot

互斥对象 Mutex

管道对象 Pipe

进程对象 Process

信号灯对象 Semaphore

...

内核对象的结构:

公用部分(安全描述符、计数器) + 个性部分

句柄、Windows数据类型:

WORD:16位无符号整型数据

DWORD:32位无符号整型数据(DWORD32)

DWORD64:64位无符号整型数据

INT:32位有符号整型数据类型

INT_PTR:指向INT数据类型的指针类型

INT32:32位符号整型

INT64:64位符号整型

UINT:无符号INT

LONG:32位符号整型(LONG32)

ULONG:无符号LONG

LONGLONG:64位符号整型(LONG64)

SHORT:无符号短整型(16位)

LPARAM:消息的L参数

WPARAM:消息的W参数

HANDLE:对象的句柄,最基本的句柄类型

HICON:图标的句柄

HINSTANCE:程序实例的句柄

HKEY:注册表键的句柄

HMODULE:模块的句柄

HWND:窗口的句柄

LPSTR:字符指针,也就是字符串变量

LPCSTR:字符串常量

LPCTSTR:根据环境配置,如果定义了UNICODE宏,则是LPCWSTR类型,否则则为LPCSTR类型

LPCWSTR:UNICODE字符串常量

LPDWORD:指向DWORD类型数据的指针

CHAR:8比特字节

TCHAR:如果定义了UNICODE,则为WCHAR,否则为CHAR

UCHAR:无符号CHAR

WCHAR:16位Unicode字符

BOOL:布尔型变量

BYTE:字节类型(8位)

CONST:常量

FLOAT:浮点数据类型

SIZE_T:表示内存大小,以字节为单位,其最大值是CPU最大寻址范围

VOID:无类型,相当于标准C语言中的void

WINAPI:Windows API的函数调用方式,常见于SDK头文件中对API函数的声明中,相当于_stdcall(更严格地说,这不是数据类型,而是一种函数调用约定

BYTE 8位 unsigned char

CHAR 8位 char

BOOL 16位 int

DWORD 32位 unsigned long int

HANDLE 一般句柄

HWND 32位 long int

LONG 32位 long int

LPCSTR 指向字符串的 const 指针

LPSTR 指向字符串的指针

SHORT 16位短整数

UINT 32位无符号长整数

WORD 16位无符号短整数

BITMAP 独立于逻辑设备的位图(DIB)

LOGBRUSH 逻辑刷

LOGFONT 逻辑字体

LOGPEN 逻辑笔

MSG 窗口消息

POINT 点

RECT 矩形

WNDCLASS 窗口类结构

hBitmap 为保存DIB图像信息的内存域的句柄

hBrush 当画图时用于填满设备范围的刷子的句柄

hCtl 子窗口控件的句柄

hCursor 鼠标光标句柄

hDc 设备描述表句柄

hDlg 文本字体的句柄

hFont 文本字体的句柄

hIcon 图标的句柄

hInstance windows应用程序实例句柄

hMem 内存块句柄

hMenu 菜单或弹出式菜单句柄

hModule 模式的句柄,常用于从一可执行文件获取资源数据

hPalette 颜色调色板

hPen 当在设备上画图时用于指明线型的笔的句柄

hRgn 在窗口上剪贴一块区域的句柄

hTask 独立于已执行的任务的句柄

hWnd 窗口句柄

持续更新中...

Windows核心编程随笔的更多相关文章

  1. windows核心编程 - 线程同步机制

    线程同步机制 常用的线程同步机制有很多种,主要分为用户模式和内核对象两类:其中 用户模式包括:原子操作.关键代码段 内核对象包括:时间内核对象(Event).等待定时器内核对象(WaitableTim ...

  2. windows核心编程---第九章 同步设备IO与异步设备IO之同步IO

    同步设备IO 所谓同步IO是指线程在发起IO请求后会被挂起,IO完成后继续执行. 异步IO是指:线程发起IO请求后并不会挂起而是继续执行.IO完毕后会得到设备的通知.而IO完成端口就是实现这种通知的很 ...

  3. windows核心编程---第八章 使用内核对象进行线程同步

    使用内核对象进行线程同步. 前面我们介绍了用户模式下线程同步的几种方式.在用户模式下进行线程同步的最大好处就是速度非常快.因此当需要使用线程同步时用户模式下的线程同步是首选. 但是用户模式下的线程同步 ...

  4. windows核心编程---第二章 字符和字符串处理

        使用vc编程时项目-->属性-->常规栏下我们可以设置项目字符集合,它可以是ANSI(多字节)字符集,也可以是unicode字符集.一般情况下说Unicode都是指UTF-16.也 ...

  5. 回忆读windows 核心编程

    看<windows 核心编程> 第五版到纤程了,下一章节即将介绍内存体系编程.如果做window平台下的开发,我感觉此书一定要读.记得开始讲解了window的基础,然后讲解内核对象.内核对 ...

  6. 《Windows核心编程》第5版 学习进度备忘

    学习资源:<Windows核心编程>第5版 知识基础支持: 本书与<Windows程序设计>第5版珍藏版结合很好,二者重叠内容不多,二者互补性强,而且相关方面的优秀书籍 跳过的 ...

  7. 【windows核心编程】 第八章 用户模式下的线程同步

    Windows核心编程 第八章 用户模式下的线程同步 1. 线程之间通信发生在以下两种情况: ①    需要让多个线程同时访问一个共享资源,同时不能破坏资源的完整性 ②    一个线程需要通知其他线程 ...

  8. 【windows核心编程】 第六章 线程基础

    Windows核心编程 第六章 线程基础 欢迎转载 转载请注明出处:http://www.cnblogs.com/cuish/p/3145214.html 1. 线程的组成 ①    一个是线程的内核 ...

  9. windows核心编程-信号量(semaphore)

    线程同步的方式主要有:临界区.互斥区.事件.信号量四种方式. 前边讲过了互斥器线程同步-----windows核心编程-互斥器(Mutexes),这章我来介绍一下信号量(semaphore)线程同步. ...

随机推荐

  1. spring-AOP动态代理,以及aspectJ的xml配置或注解配置方法,各个拦截器的使用顺序

    package com.itheima.aspect; public class MyAspect { public void check_Permissions(){ System.out.prin ...

  2. Pycharm----显示tab制表符

    设置前: 设置后: 操作方法:

  3. 重构CMDB,避免运维之耻

    CMDB,几乎是每个运维人都绕不过去的字眼,但又是很多运维人的痛,因为CMDB很少有成功的,因此我也把它称之为运维人的耻辱. 那么到底错在哪儿了?该如何去重构它? 今天我想从我的角度来和大家探讨一下业 ...

  4. 第90题:子集II

    一. 问题描述 给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: [1,2,2] 输出: [ [2], [1], [1, ...

  5. C# Stopwatch 使用

    static IEnumerable<int> SampleData() { ; var r = new Random(); , arraySize).Select(x => r.N ...

  6. 出现错误时返回异常 MVC

    在使用MVC的时候,会出现异常提醒: 1,当在Controller出现错误的时候,我们可以直接返回,即return  view()返回视图. ViewBag.Msg("产品或赠品不存在&qu ...

  7. python基础-垃圾回收机制

    垃圾回收 Python中的垃圾回收是以引用计数为主,分代收集为辅.引用计数的缺陷是循环引用的问题. 引用计数 原理:当一个对象的引用被创建或者复制时,对象的引用计数加1:当一个对象的引用被销毁时,对象 ...

  8. Luogu5339 [TJOI2019]唱、跳、rap和篮球 【生成函数,NTT】

    当时看到这道题的时候我的脑子可能是这样的: My left brain has nothing right, and my right brain has nothing left. 总之,看到&qu ...

  9. WPF中,Grid与Table的区别(英文)-转载

    原文地址:http://blog.csdn.net/johnsuna/article/details/1742799 How is Grid Different from Table?Table an ...

  10. Centos 查看CPU个数、核心数等信息

    总核数 = 物理CPU个数 X 每颗物理CPU的核数 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数 查看物理CPU个数 cat /proc/cpuinfo| grep & ...