Asura 的笔记本 https://luodaoyi.com/ zh-CN 编程比吸毒还要上瘾 Fri, 04 May 2018 02:35:24 +0000 Fri, 04 May 2018 02:35:24 +0000 以文件为后背存储区的内存交换文件 https://luodaoyi.com/p/a-memory-exchange-file-with-a-file-as-a-back-store.html https://luodaoyi.com/p/a-memory-exchange-file-with-a-file-as-a-back-store.html Fri, 04 May 2018 02:35:24 +0000 luodaoyi 以文件为后背存储区的内存交换文件

各种后备存储器的内存映射文件

  • 磁盘中文件系统的具体文件为后备存储的页交换文件(文件映射)
  • 页交换文件("虚拟内存")为后备存储器的页交换文件(共享内存)

页交换文件("虚拟内存")

通过CreateFileMapping api 创建文件映射内核对象,在内存中申请空间(物理内存和虚拟内存)
通过MapViewOfFile 在响应的进程虚拟内存空间中预定对应空间,并且把上一步的内存映射到进程虚拟空间中。
这样就实现了共享内存

具体磁盘文件

CreateFileMapping 直接映射文件到进程虚拟空间中

映象类型的内存块和映射类型的内存块

映象类型的文件类型需要exe dll等文件
而映射类型则只要是打开的文件都可以。

操作文件需要用到的api

//创建或打开指定文件的文件映射对象

HANDLE CreateFile
(
  LPCTSTR lpFileName,        // 文件路径
  DWORD dwDesiredAccess,  // 访问权限
  DWORD dwShareMode,        // 共享模式
  LPSECURITY_ATTRIBUTES lpSecurityAttributes, // SD
  DWORD dwCreationDisposition,     // 创建/打开方式
  DWORD dwFlagsAndAttributes,      // 文件属性
  HANDLE hTemplateFile            // 模板相关
);

//创建或打开指定文件的文件映射对象
HANDLE CreateFileMapping
(
    HANDLE hFile,                           // 要映射的文件句柄    LPSECURITY_ATTRIBUTES lpAttributes, // 安全属性
    DWORD flProtect,                      // 保护属性
    DWORD dwMaximumSizeHigh, // 映射区域最大大小高32位 
    DWORD dwMaximumSizeLow,  // 映射区域最大大小低32位     LPCTSTR lpName                      // 映射对象的名字
);

//创建映射
LPVOID MapViewOfFile
(
  HANDLE hFileMappingObject,// 文件映射对象句柄
  DWORD dwDesiredAccess,    // 访问的保护属性  DWORD dwFileOffsetHigh,      // 映射的内容在文件中的偏移
  DWORD dwFileOffsetLow,      // 映射的内容在文件中的偏移  类似于 offset
  SIZE_T dwNumberOfBytesToMap  // 映射的文件内容大小  类似于 limit

);
]]>
0 https://luodaoyi.com/p/a-memory-exchange-file-with-a-file-as-a-back-store.html#comments https://luodaoyi.com/feed/p/a-memory-exchange-file-with-a-file-as-a-back-store.html
页交换文件与内存映射文件 https://luodaoyi.com/p/page-exchange-file-and-memory-mapping-file.html https://luodaoyi.com/p/page-exchange-file-and-memory-mapping-file.html Thu, 03 May 2018 15:58:00 +0000 luodaoyi 页交换文件与内存映射文件

内存的几种状态和类型

私有类型:

使用VitualAlloc申请分配/调拨内存后,申请的内存只能被当前进程使用。其他进程无法访问。这就是所谓的私有内存

映射类型 -> 页交换文件(虚拟内存)

页交换文件补充了我们的物理内存的不足。在内存中长时间不活跃的数据,系统会将内存写入页交换文件。用以节省内存,所以页交换文件也是计算机内存的一部分

在开启了相应功能后,页交换文件就静静的躺在 c盘根目录,名字为pagefile.sys

映射类型 mapping:

页交互文件除了可以应急存储不活跃数据以外,还可以开辟空间作为内存映射空间
可以用来作为进程间共享的内存,实现进程间通讯。(以内存形式可以被映射到多个进程)

映象类型 image:
操作系统在加载可执行文件(exe)和模块(dll)的时候,为了快速启动和节省内存,操作系统使用了映象。将文件映射到进程虚拟内存空间中。与映射(mapping)内存的从页交换文件中映射到内存中不同,映象直接把源文件从磁盘中映射到进程虚拟内存空间中(相当于临时页交换文件)。

因为会映射到多个进程,为了防止被随意改的安全。在挂载磁盘文件到进程虚拟内存空间之前,会在系统的页交换文件中申请相同大小的空间,但是不拷贝数据,并且加上PAGE_WRITECOPY写拷贝属性,此时再去挂载到进程虚拟内存空间。

当进程在进程内部改写dll的数据的时候,也就是写那块被标记为写拷贝属性内存的时候。此时会把要改的数据拷贝到页交互文件中,与此同时。内存的映射指针也从文件指向了页交换文件。也就是此时其实改的是页交换文件而不是源文件了。这样一来不同进程就可以公用exe文件并且可以随意修改而不会相互影响了

映射类型 - 创建共享内存

//创建文件映射对象

HANDLE CreateFileMapping(
 HANDLE hFile,                       // 文件句柄,如果是真实文件则需要填写,共享内存需要填写宏 INVALID_HANDLE_VALUE
 LPSECURITY_ATTRIBUTES lpAttributes, // 安全描述
 DWORD flProtect,                    // 页面保护属性
 DWORD dwMaximumSizeHigh,            // 文件映射对象的最大大小的高位DWORD (null)
 DWORD dwMaximumSizeLow,             // 文件映射对象的最大大小的低位DWORD (大小)
 LPCTSTR lpName                      // 名字指针
);

//映射到虚拟地址空间 将文件映射的视图映射到调用进程的地址空间中。
LPVOID MapViewOfFile(
 HANDLE hFileMappingObject,   // 一个文件映射对象的句柄。CreateFileMapping和 OpenFileMapping函数返回该句柄。
 DWORD dwDesiredAccess,       // 文件映射对象的访问类型,它决定页面的保护
 DWORD dwFileOffsetHigh,      // 文件偏移量的高位DWORD。
 DWORD dwFileOffsetLow,       // 始位置的文件偏移量的低位DWORD
 SIZE_T dwNumberOfBytesToMap  // 映射到视图的文件映射的字节数
);

//MapViewOfFile 设置的权限指的是 进程使用进程的内存虚拟空间中所生效的权限
//CreateFileMapping 设置的权限是 页交换文件中映射的内存的访问权限
//在同一个 handel中 MapViewOfFile 的权限必须小于或等于INVALID_HANDLE_VALUE所声明的权限

内存访问

]]>
0 https://luodaoyi.com/p/page-exchange-file-and-memory-mapping-file.html#comments https://luodaoyi.com/feed/p/page-exchange-file-and-memory-mapping-file.html
物理内存和虚拟内存的关系 https://luodaoyi.com/p/the-relationship-between-physical-memory-and-virtual-memory.html https://luodaoyi.com/p/the-relationship-between-physical-memory-and-virtual-memory.html Mon, 23 Apr 2018 14:48:00 +0000 luodaoyi 物理内存和虚拟内存的关系

进程容器中4GB空间的内容分布

在所谓的4GB空间内,系统内核占据了高2GB的空间,普通进程看不见摸不着,而且高2GB的空间是全局共享。全局就那么一份,各个进程间共享

观察进程内存分布,我们发现进程中真正使用的内存远远不到2gb,而且地址不是连续的。说明操作系统并不是一次性吧内存都给予进程

其实操作系统非常鸡贼,它只分配进程当前需要使用的内存,不需要的一律不分配

在进程中有一台地址规则,和物理内存有映射关系

内存页

私有内存的分配 (相关win32 api)

//申请内存(预定区域/调拨物理页)
LPVOID VirtualAlloc
(
    LPVOID lpAddress,          // 申请虚拟内存的地址 一般情况下填NULL 由系统指定地址
    SIZE_T dwSize,             // 申请内存块的大小 内存分配按照内存页`0x1000` (64k)为最小单位,所以这里最好填写 `0x1000`的整数倍(64k整数倍)
    DWORD flAllocationType,  // 申请内存的状态
    DWORD flProtect            // 申请内存的保护属性
);
//释放内存(释放区域/撤销调拨)
BOOL VirtualFree
(
    LPVOID lpAddress,     // 释放的内存地址
    SIZE_T dwSize,        // 释放的内存大小
    DWORD dwFreeType      // 释放内存的方式
);


//内存块的类型
闲置      FREE
私有      PRIVATE
映象      IMAGE
映射      MAPPED

//内存块的状态
预定      RESERVE
调拨      COMMIT
空闲      FREE

//预定:在我自己的虚拟内存空间中先站住位置,但是并不分配物理内存
//调拨:真正的分配了物理页,物理内存
]]>
0 https://luodaoyi.com/p/the-relationship-between-physical-memory-and-virtual-memory.html#comments https://luodaoyi.com/feed/p/the-relationship-between-physical-memory-and-virtual-memory.html
事件和线程同步 https://luodaoyi.com/p/event-and-thread-synchronization.html https://luodaoyi.com/p/event-and-thread-synchronization.html Wed, 18 Apr 2018 16:53:40 +0000 luodaoyi 事件和线程同步

函数

//创建一个时间对象

HANDLE CreateEvent(
  LPSECURITY_ATTRIBUTES lpEventAttributes, // SD 安全属性
  BOOL bManualReset,                       // reset type 0自动复位(互斥)、1手动复位(通知模式)
  BOOL bInitialState,                      // initial state 初始创建时时间是否具备信号
  LPCTSTR lpName                           // object name 对象的名称
);

//将目标事件对象设置为有信号的(同时通知其他线程)
BOOL SetEvent(  
    HANDLE hEvent   // handle to event //目标事件的句柄
);
//将目标事件对象设置为无信号的
BOOL ResetEvent(  
    HANDLE hEvent   // handle to event 目标事件的句柄
);

通知模式

回顾互斥模式

在线程间共享资源的时候,它们间的状态是互相排斥的,当A拿到所有权使用共享资源的时候,B线程是被排斥的,只有当A交出所有权的时候B才能够使用

中有个属性 标识符 比如说标识符为1的时候代表无人使用(有信号的),这个时候A和B回去抢夺锁,使用WaitForSingleObject来检测标识符,先到先得,比如线程A先到获得了信号,A就会获取信号回去所有权,此时锁会自动设置为0 代表无信号,此时A获得了临界区,可以访问共享资源,此时即使发生线程切换,也可保证共享资源的完整。当A使用完毕后,使用ReleaseMutex归还所有权,那么此时互斥锁状态改为1 有信号 回归无人使用。其他线程继续抢夺

通知模式

通知模式,A 或者B线程的WaitForSingleObject检测信号,当使用SetEventAPI发出信号的时候,与互斥模式不同,通知模式检测到 标识为 1的的时候 WaitForSingleObject 会立即返回往下执行,但不会修改信号标识,发生线程切换后,其他线程也可以检测到1 继续执行 同样不会修改。此时就像通知一样,其他的线程都可以往下继续执行了。

线程同步

  • 线程的互斥

    当某个共享资源被多个线程共同访问的时候,在同一时间只能有一个线程在访问我们的资源
    
  • 线程的同步

    线程的同步建立在线程互斥的基础上
    多个线程访问同一个资源的时候在互斥的基础上还有`有序`
    

例如:AB同时访问一个资源的时候,要求AB轮流有序的访问,而不是处于一种先到先得的抢夺状态

同步 = 互斥 + 有序

]]>
0 https://luodaoyi.com/p/event-and-thread-synchronization.html#comments https://luodaoyi.com/feed/p/event-and-thread-synchronization.html
ubuntu sudo 免密码 https://luodaoyi.com/p/ubuntu-sudo-free-password.html https://luodaoyi.com/p/ubuntu-sudo-free-password.html Wed, 18 Apr 2018 06:03:22 +0000 luodaoyi ubuntu sudo 免密码
cd /etc/sudoers.d  
  
sudo touch nopasswd4sudo  
  
sudo vi nopasswd4sudo  
  
//输入 
ubuntu ALL=(ALL) NOPASSWD : ALL  
  
ESC :wq!  
]]>
0 https://luodaoyi.com/p/ubuntu-sudo-free-password.html#comments https://luodaoyi.com/feed/p/ubuntu-sudo-free-password.html
临界区、线程锁和互斥体 https://luodaoyi.com/p/critical-area-thread-lock-and-mutex.html https://luodaoyi.com/p/critical-area-thread-lock-and-mutex.html Tue, 17 Apr 2018 19:05:41 +0000 luodaoyi 临界区、线程锁和互斥体

不可重入函数

不可重入函数: 当这个函数返回前,不可以被其他线程调用

原因:

printf : 访问了引用全局变量stdout
malloc : 引用了全局内存分配表
free   : 引用的全局内存分配表

类似的 假如我在我的线程中使用全局变量会不会出现类似问题?

坑:

当多线程同时去访问所谓不可重入函数的时候,当A线程调用printf执行完毕之前,发生了线程切换去执行B线程,而B线程如果又再等待A线程的时候,那么就会有几率触发bug,永久等待。。。。

临界区 -共享资源

比如上图

尽管A B C D 四个线程都回去访问全局变量。而且在访问一半的时候有可能会出现线程上下文切换。但是我们在变量前面加了一把锁,比如A线程访问一半时 发生了线程切换。此时B线程再去访问也是无法访问的。等线程切换回A 之后 A 访问完毕释放。其他线程才可以正常访问

有多个线程同时使用的变量,我们称为临界变量

同一进程中,不同线程的共享资源访问解决办法:线程锁

如左图,当A线程访问共享资源使用一半的时候,如果发生线程切换,B线程去访问并修改了共享资源,那么切换回A的时候拿到的值必然是错误的。

如何简单的解决这种问题?

此时引入线程锁的概念:

当 线程访问共享资源的时候 需要取得锁,取得锁的才可以访问资源,访问完毕后释放锁,其他线程才可以访问

  • 创建全局变量

    CRITICAL_SECTION cs;            //创建令牌
  • 初始化全局变量

    InitializeCriticalSection(&cs); //初始化令牌
  • 实现临界区

    EnterCriticalSection(&cs);      //进入临界区
    LeaveCriticalSection(&cs);      //离开临界区

跨进程访问共享资源 :互斥体

线程间可以通过线程锁来防止发生错误,进程间也可以通过锁来限制

这就是互斥体

因为需要跨进程加锁,所以互斥体不能存在用户区中。只能存在于同时访问共享资源的共享内核区

常用的互斥体的操作:


//创建互斥体
HANDLE CreateMutex
(
    LPSECURITY_ATTRIBUTES lpMutexAttributes,  // 安全属性
    BOOL bInitialOwner,                       // 初始信号
    LPCTSTR lpName                            // 对象名称
);
//等待信号到达
DWORD WaitForSingleObject
(
    HANDLE hHandle,                           // 等待对象的句柄
    DWORD dwMilliseconds                      // 超时时间
);
//释放互斥体
BOOL ReleaseMutex
(  
  HANDLE hMutex                              // 释放的内核对象
);
  1. 加入A进程先创建的互斥体,那么B进程如何找到A创建的互斥体?
  2. 加入我们不能确定AB两个进程谁先启动,那么由会来先创建我们的互斥体?谁后来打开前者创建的互斥体?

    一个进程调用`CreateMutex` 时候如果内核中没有名字为参数`lpName`的互斥体的时候,系统就会创建对象,不并且返回句柄。当其他进程中的线程访问的时候,也调用`CreateMutex`,并且`lpName` 参数与前面调用的进程相同的时候,在内核区中已经有此名字的互斥体,此时不会创建新对象,会直接返回之前内核中创建好的对象
    

线程锁与互斥体的区别

线程锁与互斥体的区别:

  1. 线程锁只能用于单个进程内部的线程控制
  2. 互斥体可以设定等待超时,但线程锁不能
  3. 线程意外终结时,Mutex可以避免无限等待
  4. Mutex效率没有线程锁高
]]>
0 https://luodaoyi.com/p/critical-area-thread-lock-and-mutex.html#comments https://luodaoyi.com/feed/p/critical-area-thread-lock-and-mutex.html
vmware 6 虚拟化 全系列 序列号 https://luodaoyi.com/p/vmware-6-virtualized-full-series-serial-number.html https://luodaoyi.com/p/vmware-6-virtualized-full-series-serial-number.html Mon, 16 Apr 2018 13:40:27 +0000 luodaoyi vmware 6 虚拟化 全系列 序列号

vSphere 6 Hypervisor

HY0XH-D508H-081U8-JA2GH-CCUM2

4C4WK-8KH8L-H85J0-UHCNK-8CKQ8

NV09R-2W007-08D38-CA956-33U28

JU400-6EK4L-080V9-QT8EP-2KAQ2

vSphere 6 Hypervisor for Embedded OEMs

NC6HH-26J4N-48098-Y0AX0-1GA66

HY0J0-6L28H-081W8-4TCN0-32RP0

0V012-002DJ-480T1-UHAE0-9GULF

4G6WR-A0K4M-08420-J8CN6-8A2QA

vSphere 6 Desktop Host

MF00U-65K53-H8DF9-Q20ZH-26R40

JV6D2-6YLDN-088C0-Q92N2-8Z00A

HG49R-2234J-08EJ8-WC9E2-87H2D

NV6TR-D4HD1-M84L1-P19QM-0PK3D

vSphere 6 for vCloud Service Provider Standard

JG2JK-DM01L-M8101-J8AZH-3LUH2

JZ41H-0X153-H8579-A32ZK-16H20

4A0HU-DU084-H8990-C9376-16KHF

1V0EA-FNK51-H85K8-H1AN6-2U8PD

vCloud Suite 6 Standard

HV0N8-AC382-H8ET1-631X6-23K10

HU4EA-A52E2-H89V9-T295K-0V8Q4

NZ4XH-2VK43-H8D30-6L974-97800

NU2DH-DW145-H81Y8-KL0QP-9GAQD

vCloud Suite 6 Advanced

MU2HU-DEHEQ-M85U0-N3356-07A5D

HC0R0-AZJE3-08EF1-T99E6-86R32

HG0JK-F4J1M-08E49-L91Q2-8K832

5U40R-D615H-M8EZ8-D82ZP-12848

vCloud Suite 6 Enterprise

JY04H-DFJ01-M8869-428EM-96R60

5Y04R-AYKE3-H8DR8-NK0EM-1UAL2

NC682-0GJ4P-08EM1-32ANM-0AU6F

NZ2JR-6U286-H81N0-8V3Z6-1FHH2

vSphere with Operations Management 6 Standard

HZ4J8-AWJ4Q-M8560-YT3Q6-0F052

JU24R-67H53-H8DF1-4L17K-8U208

MY6DK-0K1D2-M80T0-UR1Z4-8CK42

JU4E2-2W085-M8D78-M0AZM-AARKF

vSphere with Operations Management 6 Enterprise

JA60R-2JK84-M8DQ1-4L9N0-8VRP2

MG4T2-FY29P-480F9-9H0X0-16K1D

1U65R-2Y24N-M8DR1-U2C50-16HQ8

1V2HU-26KD1-08D60-LH9GK-CPU6F

vSphere 6 Foundation

JA6R2-DELEK-H8EP8-83AXP-07RQ8

0G6EA-07J5M-M8991-TJ0Z6-2U87D

NU61R-ADKD2-488M9-CV8NH-A6K30

0Y050-A3L42-084C9-6LCGP-3AR3D

vSphere 6 Foundation for Embedded OEMs

HA2JK-42HD4-H80C0-79CZ0-1L012

JY2E2-6W11L-H81K0-0A274-3ZU36

4G6HU-FF05N-085L1-R0ANM-C705F

4Y2TA-2R08P-H80H9-N317H-1ZK16

vSphere 6 Embedded Essentials

NY6M2-D5H8L-489D0-280Z0-2Q004

HA080-FP203-M8830-XH9QM-3PU2D

JF0NH-AGJ0P-H8EW0-2U85H-AU0QA

HU09A-6F04H-08E90-G28Z6-1A808

vSphere 6 Embedded Foundation

1A6H8-DT2D3-H8DR8-5L9EK-2AH18

4V088-D93DL-H89H9-3V8QH-C7H3D

JU28A-DR3DN-489H9-JC8XH-CZ052

1U69U-0AL9L-08171-UHCXK-9622A

vSphere 6 Essentials

NG2T0-AZ08N-484V0-KRC52-87K2D

JY412-8MKEH-489U0-KL2Q0-0ZUQ8

0F44K-85J17-489U8-JH9N6-8F060

4G28H-0CLDQ-H80J0-V3AZ0-862KA

vSphere 6 Essentials for Retail and Branch Offices

4U6NH-4D0EK-08EU9-JLCZ6-AU0J4

0G690-4F3EQ-M80G9-AR35M-AAUQ0

NV29K-8PLE3-480U1-T9970-A6RJD

1Z2MK-6T243-484J0-6K954-AYULD

vSphere 6 Essentials Plus

MU2MR-6HH1P-48E11-8J3G4-2Y8NF

HY0JR-AHK4H-08EM8-W22X6-0KU3F

4Z0RH-0YK55-48089-820Z6-AC852

JZ4HR-DJJ50-M84G0-LJ0G4-A22QF

vSphere 6 Essentials Plus for Retail and Branch Offices

1Y24U-6K05Q-48989-PR9G2-CA262

NV0XK-6ML00-H8D21-FR954-AG0ND

1G2MA-A2201-48DJ1-HC2E0-3ZA14

1V65R-0ZJ55-08870-KLAQH-0UA3F

vSphere 6 Standard

MG2T2-8FK0Q-H88H0-6RC50-9LU58

JU600-6YH91-M8DR8-D1CGP-330ND

HV2WH-D2192-M84K1-RLC56-1A862

HG6R2-8NH52-088H9-X33QP-C68KD

vSphere 6 Standard for Embedded OEMs

4F6XU-ADK50-488K0-UJ0ZM-1U8J8

0Z29R-A028L-M80J9-3H3N6-8UU2D

1Y68K-AG206-M8E38-298N0-8VUJD

HF252-0X391-H8029-H835M-33834

vSphere 6 Enterprise

5Y04A-8934J-M85P1-3K37H-9P04D

JA2NH-2Z191-08501-NCAX2-2VK4F

0F2T2-DCK93-M88M8-7J9E4-16RJ0

NU0EK-05100-M80N9-501N2-8G81D

vSphere 6 Enterprise for Embedded OEMs

0V050-0XL9N-M85A8-LU1GK-0UA52

NG6H2-FT186-H8EV8-UH9NP-1F208

5Y400-4G2EJ-481W8-R80GM-2K2NF

4Z44H-4R19K-H88T8-CT87P-0CKMD

vSphere 6 Enterprise Plus

1F6XH-8VJ9L-481Y9-L835P-CFHHA

1G28U-AW18P-08189-72AE6-9URP8

4Y29R-D034H-48561-RLAG0-ACU40

JU640-0JKE3-088J9-GRCXK-2PRH6

vSphere 6 Enterprise Plus for Embedded OEMs

1U0H2-DX354-H8961-Z2CN6-3C0M4

MY2DH-AFKDL-081A9-WR1XK-13HH8

5V2E2-AMLE4-08EF1-QHAZM-8YK20

4V692-D3KEL-M8088-NUAQ6-1Q0MD

vCenter Server 6 Essentials

NU68U-6D04K-08EV8-GK95K-9LRN6

HG2T0-6F3D3-489L9-2T9QH-3QR12

HZ05H-0W1EL-08EC0-E8AEK-8CKMF

4V24K-0J34Q-084D8-X19E2-03U2D

vCenter Server 6 Foundation

MV692-29093-M85H0-6RC76-1Q230

5A6MU-0N057-08EF8-NT1Q0-2FU7D

5C21A-6XK4H-089K8-2385M-3PAM8

NG6RA-ANK91-089Z9-P93ZH-0G016

vCenter Server 6 Standard

HG612-FH19H-08DL1-V19X2-1VKND

NU4JA-4V2DQ-48428-T32GK-8VRN4

0Y4H2-8P217-H8900-M8AE4-2LH44

NA658-2308J-08809-93AQ6-278J0

vCenter Server 6 Standard for Embedded OEMs

1G2NU-AZL54-484X0-3TAN0-9GH2A

JG69A-2T155-088J1-00A5M-1C0L8

HC45A-DEK1M-081C9-QKCZ0-C2K3D

NC4M8-2CL0M-08159-5V0E2-1GR3A

Virual SAN Standard

HZ2E0-0RKDL-485Y8-3L150-AYU52

NA69A-2Q385-M84D1-13370-322H2

HA0RU-FEL03-M8408-AUA7M-2U8JD

0F0J8-8YH8P-488F1-JCAN0-1V21D

Virual SAN

JU2D8-4CL82-088R1-RLAX2-3K8L0

1A6JU-0JK0P-481W0-70AE0-2QAJ8

4C48A-27HDH-48001-YH2E4-9ZUQF

4V252-FHH8K-480A1-VCAQM-A2KQ4

Virual SAN for Desktop

4F25K-4N392-M8161-132XP-1GR3F

0A4MR-49K93-08890-FR97K-93R4A

JU2EH-08K4N-M8DC0-4T3E2-33UH4

4Z6MU-2J383-481N1-G91QP-1Y2PA

]]>
0 https://luodaoyi.com/p/vmware-6-virtualized-full-series-serial-number.html#comments https://luodaoyi.com/feed/p/vmware-6-virtualized-full-series-serial-number.html
线程的创建和控制 https://luodaoyi.com/p/the-creation-and-control-of-threads.html https://luodaoyi.com/p/the-creation-and-control-of-threads.html Wed, 11 Apr 2018 18:56:00 +0000 luodaoyi 线程的创建和控制

进程和线程的关系:进程提供资源,线程使用资源完成工作

创建线程函数

HANDLE CreateThread(
  LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD /安全属性 
  DWORD dwStackSize,                        // initial stack size //线程栈大小-
  LPTHREAD_START_ROUTINE lpStartAddress,    // thread function //线程代码
  LPVOID lpParameter,                       // thread argument //线程参数
  DWORD dwCreationFlags,                    // creation option //创建标识
  LPDWORD lpThreadId                        // thread identifier //线程id
);

线程的控制

//线程等待
//等待一个
DWORD WaitForSingleObject(  
    HANDLE hHandle,        // handle to object,监视对象的句柄
    DWORD dwMilliseconds   // time-out interval 指定超时等待时间 毫秒为单位
);
//等待多个
DWORD WaitForMultipleObjects(
  DWORD nCount,             // number of handles in array,句柄数量
  CONST HANDLE *lpHandles,  // object-handle array 句柄数组
  BOOL fWaitAll,            // wait option 是否全等待/TRUE 全部结束才返回/False 一个结束就返回
  DWORD dwMilliseconds      // time-out interval,超时时间
);
//获取线程的退出代码
BOOL GetExitCodeThread(  
    HANDLE hThread,      // handle to the thread
    LPDWORD lpExitCode   // termination status
);

更多的API

HANDLE CreateThread(
  LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD /安全属性 
  DWORD dwStackSize,                        // initial stack size //线程栈大小-
  LPTHREAD_START_ROUTINE lpStartAddress,    // thread function //线程代码
  LPVOID lpParameter,                       // thread argument //线程参数
  DWORD dwCreationFlags,                    // creation option //创建标识
  LPDWORD lpThreadId                        // thread identifier //线程id
);

创建标志位:
指定一个标志来控制线程的创建,如果指定了 CREATE_SUSPENDED 标志,则线程是在一个挂起状态下创建的,并且在调用了ResumeThread ()函数之前不会运行,如果这个值为零,那么线程在创建之后立即运行

//线程回复
DWORD ResumeThread(  
    HANDLE hThread   // handle to thread 目标线程的句柄
);

//让自己停下来
VOID Sleep(  
    DWORD dwMilliseconds   // sleep time 暂停时间
);

//让目标停下来

DWORD SuspendThread(  
    HANDLE hThread   // handle to thread 挂起目标的句柄
);

挂起计数:

API ResumeThread 提到了挂起计数

线程在系统中通过线程内核对象管理,线程内核对象有一个 挂起计数器
用于统计当前线程被挂起的次数
当调用SuspendThread 挂起计数就会+1
调用ResumeThread 挂起计数就会-1

当挂起计数为0时,线程将会正常执行

线程的本质

  • 一个单核CPU 一瞬间只能做一件事,那如何实现多线程在一个进程内“同时”干不同的工作

    
    >操作系统会给每一个线程都分配一定的时间,在一点时间内CPU加载对应的线程上下文执行线程对应代码和EIP所指向的位置、堆栈等,时间过后就保存当前执行的环境,然后更换线程上下文,来回调度。对于CPU来说 一瞬间就做了一件事,但是CPU速度非常快。在我们看起来就是一起做很多事情
    
  • 什么是线程?

    一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成
    
    线程是WINDOWS中最基本的调度单位
    
    线程调度
    
    理论上A、B、C、D 进程 轮流调度执行
    但是实际上 windows系统是以线程为单位轮流调度执行的。原因很复杂,有一套复杂的逻辑
    根据一些条件灵活调度,比如线程优先级、饥饿度等
    

  • 获取线程的上下文CONTEXT结构体

    BOOL GetThreadContext(  
        HANDLE hThread,       // handle to thread with context 目标线程句柄
        LPCONTEXT lpContext   // context structure 结构体缓存
     );

练习:

通过创建快照CreateToolhelp32Snapshot的方式,遍历所有线程
每个进程有一个PID,线程也有TID,找到目标进程中所有线程,然后全部挂起。实现一个线程挂起功能

]]>
0 https://luodaoyi.com/p/the-creation-and-control-of-threads.html#comments https://luodaoyi.com/feed/p/the-creation-and-control-of-threads.html
句柄表和继承 https://luodaoyi.com/p/handle-tables-and-inheritance.html https://luodaoyi.com/p/handle-tables-and-inheritance.html Mon, 09 Apr 2018 16:37:00 +0000 luodaoyi 句柄表和继承

句柄代表着备操作的对象

句柄的本质(handler)

句柄表可以看做一个非常大的结构体数组
句柄表的结构

索引值: 进程通过索引找到句柄表中对应的选项
内核对象地址: 通过地址直接找到对应的内核对象
访问掩码: 控制了访问权限
标志位: 标志改句柄能否被继承

句柄表是如何工作的:

每个进程的内核对象,都有一个句柄与之对应
操作对应进程,需要获得进程句柄。通过系统api操作

比如A要操作B进程
A会在A的句柄表中空白的位置存储B的内核地址,返回索引值 就是句柄
当操作B进程的时候 就使用句柄调用系统api操作B进程

类似于的 如果有C、D等进程和A进程一起操作B进程的话,这样一来 C.D自己的句柄表中都会存储B的内核对象地址。这么一来就带来一个问题
如果A C D 同时访问B的资源,突然间B的内核对象被销毁释放了,那么A C D三个都会出错

为了缓解此类错误,windows操作系统使用了内核对象使用计数机制:

内核对象的使用计数:

每一个内核对象都有一个使用计数的属性
每当内核对象被获得过一次,此内核对象的使用计数就会+1
当其他句柄中此内核对象的句柄销毁时,此内核对象并不会被销毁,而是使用计数-1
当内核对象的使用计数为0 的时候 就说明此时并没有其他地方再使用此内核对象了,此时内核对象就会被销毁

//销毁句柄 内核计数-1
BOOL CloseHandle
(
    HANDLE hObject //关闭的目标句柄
)

句柄的继承关系

当父进程创建子进程的时候,父进程标志位为0的,表示此条索引(句柄)不想被子进程继承

BOOL CreateProcess(
  LPCTSTR lpApplicationName,                // 路径
  LPTSTR lpCommandLine,                      // 命令行
  LPSECURITY_ATTRIBUTES lpProcessAttributes, // 进程安全属性
  LPSECURITY_ATTRIBUTES lpThreadAttributes,  // 线程安全属性
  BOOL bInheritHandles,                        // 继承标志位
  DWORD dwCreationFlags,                    // 创建标志
  LPVOID lpEnvironment,                        // 环境块
  LPCTSTR lpCurrentDirectory,                // 驱动目录
  LPSTARTUPINFO lpStartupInfo,            // 启动信息
  LPPROCESS_INFORMATION lpProcessInformation // 进程信息
);

进程标志位参数 BOOL bInheritHandles
表示了新进程(子进程)是否继承父进程句柄表中的句柄,如果为true,那么就继承父句柄表中可被继承的句柄,并且继承的句柄具有和原始句柄相同的值和访问权限

进程安全属性和线程安全属性 参数,决定是否可以由子进程(线程)继承返回的句柄。如果是NULL 则表示不能被继承

//安全属性

SECURITY_ATTRIBUTE
{
    DWORD  nLength;  //结构体宽度
    LPVOID lpSecurityDescriptor;//安全描述符
    BOOL   bInheritHandle;//被创建的句柄能否被继承
} 

//安全描述符:决定了用户的访问权限,可以由他指定哪些用  户可以访问,以及一些访问权限,一般填NULL
//句柄继承选项:决定了被创建的对象的句柄是否是可以被继  承的
]]>
0 https://luodaoyi.com/p/handle-tables-and-inheritance.html#comments https://luodaoyi.com/feed/p/handle-tables-and-inheritance.html
ListView控件 https://luodaoyi.com/p/listview-control.html https://luodaoyi.com/p/listview-control.html Sun, 08 Apr 2018 17:06:00 +0000 luodaoyi ListView控件 实现简单进程管理

用到的相关api函数

//获取控件句柄
HWND GetDlgItem(
        HWND hDlg,//获得控件所处的窗口的句柄
        int nIDDlgItem //控件id
);

//初始化列表的列 (listview插入新的一列
int ListView_InsertColumn(
    HWNDhwnd, //控件的句柄
    int iCol,  //第几列 (索引 index
    const LPLVCOLUMNpcol //结构体指针 (包含新列的结构体
);

//插入新的一行条目
int ListView_InsertItem(
        HWND hwnd,
        const LPLVITEM pitem
);
//设置条目的属性
BOOL ListView_SetItem(
        HWND hwnd, 
        const LPLVITEM pitem
);

//删除所有项目
BOOL ListView_DeleteAllItems(
        HWND hwnd
);

//标准输出格式化字符串
swprintf(buffer,L"%s,哈哈",param);
//清空
ZeroMemory(buffer);

list属性:

View-展示形式 : report-报表形式

实现一个简易任务管理器

0x1 添加listview控件

找到资源视图,双击并打开

打开工具箱,找到ListControl 拖入到dialog窗体中,调整到适当的大小

记录list控件的id

实现基本窗体代码

0x2 初始化list控件

获得控件句柄

调用初始化控件函数

初始化控件列

初始化数据

]]>
0 https://luodaoyi.com/p/listview-control.html#comments https://luodaoyi.com/feed/p/listview-control.html