1.进程可以通过以下四种方式终止:

  • 主线程的入口点函数返回(强烈推荐的方式)
  • 进程中的一个线程调用ExitProcess函数(避免这种方式)
  • 另一个进程中的线程调用TerminateProcess函数(避免这种方式)
  • 进程中的所有线程都“自然死亡”(这种情况几乎从来都不会发生)

2.应该保证只有在主线程的入口点函数返回之后,这个应用程序的进程才终止,只有这样才能保证主线程的所有资源都被正确清理。让主线程的入口点函数返回,可以保证以下操作会被执行:

  • 该线程创建的任何C++对象都将由这些对象的析构函数正确销毁。
  • 操作系统将正确释放线程栈使用的内存。
  • 系统将线程的退出代码(在进程内核对象中维护)设为入口点函数的返回值。
  • 系统递减进程内核对象的使用计数。

3.ExitProcess函数将终止进程,并设置退出代码,没有返回值,而且之后的代码永远不会被执行(对象的析构函数也无法被调用)。

4.当主线程的入口点函数(WinMain,main)返回时,会返回到C/C++运行库的启动代码,后者将正确清理进程使用的全部C运行时资源。释放了C运行时资源之后,C运行时启动代码将显示调用ExitProcess,并将入口点函数返回的值传给它。这便解释了为什么只需从主线程的入口点函数返回,就会终止整个进程。注意,进程中运行的其他任何线程都会随进程一起终止。

5.从操作系统的角度出发,一个进程在其所有线程都终止之后才会终止时正确的。但是C/C++运行库的策略是:不管进程中是否还有其他线程在运行,只要主线程从它的入口点函数返回,C/C++库就会调用ExitProcess来终止进程。但是如果入口点函数中调用的是ExitThread而不是ExitProcess或入口点函数直接返回,应用程序的主线程将停止执行,但只要进程中还有其他线程在运行,进程就不会终止。

6.任何线程都可以调用TerminateProcess来终止另一个进程或者它自己的进程。只有在无法通过其他方法来强制进程退出时才用。而且被终止的进程得不到自己要被终止的通知,也不能阻止自己被强行终止。

7.一旦进程终止,不管是如何终止的,系统会保证不留它的任何部分。绝对没有任何办法知道哪个进程是否运行过。进程在终止后绝对不会泄漏任何东西(内存会释放,文件会被关闭,内核对象计数会递减)。

8.TerminateProcess函数是异步的,函数返回时系统并不能保证进程已经被强行终止了。

9.如果一个进程中的所有线程都终止了(它们都调用了ExitThread或TerminateThread来终止了),操作系统就认为没有任何理由再保持进程的地址空间,就会终止这个进程,进程的退出代码会被设为最后一个终止的那个线程的退出代码。

10.一个进程终止时,系统会依次执行以下操作:

  • 终止进程中遗留的任何线程
  • 释放进程分配的所有用户对象和GDI对象,关闭所有内核对象(除非其他进程也打开了)
  • 进程的退出代码从STILL_ACTIVE变为传递给ExitProcess或TerminateProcess函数的代码。
  • 进程内核对象的状态变成已触发状态,这就是为什么系统中的其他线程可以挂起它们自己,直至另一个进程终止运行。
  • 进程内核对象的使用计数递减1。

Windows Internals 笔记——终止进程的更多相关文章

  1. Windows Internals 笔记——进程的权限

    1.大多数用户都用一个管理员账户来登录Windows,在Vista之前,这样的登录会创建一个安全令牌.每当有代码试图使用一个受保护的安全资源时,操作系统就会出示这个令牌.从包括Windows资源管理器 ...

  2. Windows Internals 笔记——进程

    1.一般将进程定义成一个正在运行的程序的一个实例,由以下两部分构成: 一个内核对象,操作系统用它来管理进程,内核对象也是系统保存进程统计信息的地方. 一个地址空间,其中包含所有可执行文件或DLL模块的 ...

  3. Windows Internals 笔记——线程调度

    1.线程内核对象中的CONTEXT反应了线程上一次执行时CPU寄存器的状态.大约每隔20ms,Windows都会查看所有当前存在的线程内核对象.Windows在可调度的线程内核对象中选择一个,并将上次 ...

  4. Windows Internals 笔记——线程

    1.进程有两个组成部分,一个进程内核对象和一个地址空间.线程也有两个组成部分: 一个是线程的内核对象,操作系统用它管理线程.系统还用内核对象来存放线程统计信息的地方. 一个线程栈,用于维护线程执行时所 ...

  5. Windows Internals 笔记——作业

    1.Windows提供了一个作业内核对象,它允许我们将进程组合在一起并创建一个“沙箱”来限制进程能够做什么.创建只包含一个进程的作业同样非常有用,因为这样可以对进程施加平时不能施加的限制. 2.如果进 ...

  6. Windows Internals 笔记——CreateProcess

    1.一个线程调用CreateProcess时,系统将创建一个进程内核对象,其初始使用计数为1.然后系统为新进程的主线程创建一个线程内核对象(使其计数为1). 2.CreateProcess在进程完全初 ...

  7. Windows Internals 笔记——内核对象

    1.每个内核对象都只是一个内存块,它由操作系统内核分配,并只能由操作系统内核访问.这个内存块是一个数据结构,其成员维护着与对象相关的信息. 2.调用一个会创建内核对象的函数后,函数会返回一个句柄,它标 ...

  8. Windows Internals 笔记——关联性

    1.默认情况下,Windows Vista在给线程分配处理器时,使用软关联.意思是如果其他因素都一样,系统将使线程在上一次运行的处理器上运行.让线程始终在同一个处理器上运行有助于重用仍在处理器高速缓存 ...

  9. Windows Internals 笔记——线程优先级

    1.每个线程都被赋予0(最低)~31(最高)的优先级数.当系统确定给哪个线程分配CPU时,它会首先查看优先级为31的线程,并以循环的方式进行调度.如果有优先级为31的线程可供调度,那么系统就会将CPU ...

随机推荐

  1. 解决 MariaDB无密码就可以登录的问题

    问题: 困扰了很久的问题,, 使用apt-get来安装mysql,安装好之后发现安装的是 MariaDB,如下,无需密码既可以登录了.即使使用mysqladmin设置好密码,用密码登录可以,不用密码登 ...

  2. 洛谷P1220关路灯题解

    题目 此题是一个状态转移方程还算比较多的一个区间DP,这个题也能启示我们如果某个状态不能够很好地解决问题,那么不妨试试再加一维,而且如果转移顺序不确定的话,可以试试记忆化搜索,说不定就可以比较容易的写 ...

  3. oracle表的操作SQL语句

    这篇文章的内容包括:表的増删改查,字段的増删改查,主键.外键.唯一.非空.默认约束的増删改   查看自己用户的所有表: select * from user_tab_comments;    www. ...

  4. 设置 sql_mode

    MySQL 的 sql_mode 合理设置 sql_mode 是个很容易被忽视的变量,默认值是空值,在这种设置下是可以允许一些非法操作的,比如允许一些非法数据的插入.在生产环境必须将这个值设置为严格模 ...

  5. Java使用J4L识别验证码

    1.首先要下载j4l的相应文件和jar 下载地址:http://www.java4less.com/ocrtools/ocrtools.php?info=download 2.下载完成之后解压,文件目 ...

  6. Django admin组件源码流程

    admin 组件 Django 自带的用户后台组件 用于用户便携的操作 admin 组件核心 启动 注册 设计url 启动核心代码 每个app 通过 apps.py 扫描 admin.py 文件 并执 ...

  7. JMeter5.1开发TCP协议接口脚本

    最简单的方法,就是找开发给报文,直接复制到tcp取样器中,将需要变化的值做参数化就可以了.(xml报文要去掉回车换行) 下面是一个通讯头定义 通讯头56个字节(1个字符一个字节) 3 + 9 + 9 ...

  8. <三>企业级开源仓库nexus3实战应用–使用nexus3配置maven私有仓库

    一两个星期之前,你如果在我跟前说起私服的事情,我大概会绕着你走,因为我对这个东西真的一窍不通.事实上也正如此,开发同学曾不止一次的跟我说公司的私服版本太旧了,许多新的依赖编译之后不会从远程仓库自动缓存 ...

  9. 记一次504 Gateway Time-out

    使用curl请求是超时,查了下资料原来是端口被占用,造成了死锁,记录下 首先要知道为什么会出现死锁? 在我们访问页面的时候这个端口进程就已经被使用,当我们再在页面中curl请求其他页面因为没有其他的端 ...

  10. mycat 使用

    介绍 支持SQL92标准 支持MySQL.Oracle.DB2.SQL Server.PostgreSQL等DB的常见SQL语法 遵守Mysql原生协议,跨语言,跨平台,跨数据库的通用中间件代理. 基 ...