进程(Process)是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位。程序只是一组指令的有序集合,它本身没有任何运行的含义,只是一个静态实体。而进程则不同,它是程序在某个数据集上的执行,是一个动态实体。它因创建而产生,因调度而运行,因等待资源或事件而被处于等待状态,因完成任务而被撤消,反映了一个程序在一定的数据集上运行的全部动态过程。

  线程(Thread)是进程的一个实体,是CPU调度和分派的基本单位。线程不能够独立执行,必须依存在进程中,由进程提供多个线程执行控制。从内核角度讲线程是活动体对象,而进程只是一组静态的对象集,进程必须至少拥有一个活动线程才能维持运转。





当某个应用程序调用一个创建进程的函数比如CreateProcess或者用户执行某一个程序(其实windows下用户执行一般普通程序是由explorer.exe调用CreateProcess来完成),操作系统把这个过程分成以下步骤来完成:

1.打开将要在该进程中执行的映像文件。

2.创建Windows执行体进程对象。

3.创建初始线程(栈、堆执行环境初始化及执行线程体对象)。

4.通知Windows子系统新进程创建了(子系统是操作系统的一部分它是一个协助操作系统内核管理用户态/客户方的一个子系统具体的进程为Csrss.exe)。

5.开始执行初始线程(如果创建时候指定了线程的CREATE_SUSPENDED状态则线程暂时挂起不执行)。

6.在新进程和线程环境中完成地址空间的初始化(比如加载必须的DLL和库),然后开始到进程入口执行。

到这里操作系统完成一个新进程的创建过程。下面来看下具体每一步操作系统所做的工作:

1.打开将要在该进程中执行的映像文件。

首先操作系统找到执行的Windows映像然后创建一个内存区对象,以便后面将它映射到新的进程地址空间中。





2.创建Windows执行体进程对象。

接下来操作系统调用内部的系统函数NtCreateProcess来创建一个Windwos执行体进程对象。具体步骤是:

(1)建立EPROCESS

*分配并初始化EPROCESS结构块

*从父进程处继承得到进程的亲和性掩码

*分配进程的最大最小工作集尺(由两个参数决定PsMinimumWorkingSet PsMaximumWorkingSet)

*降新进程的配额块设置为父进程配额块地址,并递增父进程配额块的引用计数

*继承Windows的设备名字空间

*将父进程进程ID保存在新进程对象的InheritedFormUniqueProcessId中

*创建该进程的主访问令牌

*初始化进程句柄表

*将新进程的退出状态设置为STATUS_PENDING





(2)创建初始的进程地址空间

*在适当的页表中创建页表项,以映射初始页面

*从MmresidentAvailablePage算出进程工作集大小

*系统空间的非换页部分和系统缓存的页表被映射到进程





(3)初始化内核进程块KPROCESS

(4)结束进程地址空间的创建过程

(5)建立PEB

(6)完成执行体进程对象的创建过程





3.创建初始线程(栈、堆执行环境初始化及执行线程体对象)。

这时候Windows执行体进程对象已经完全建立完成,但它还没有线程所以无法执行,接下来系统调用NtCreateThread来创建一个挂起的新线程它就是进程的主线程体。





4.通知Windows子系统新进程创建了(子系统是操作系统的一部分它是一个协助操作系统内核管理用户态/客户方的一个子系统具体的进程为Csrss.exe)。接下来操作系统通过客户态(Kernel32.dll)给Windows子系统(Csrss)发送一个新进程线程创建的数据消息,让子系统建立自己的进程线程管理块。当Csrss接收到该消息时候执行下面的处理:

*复制一份该进程和线程句柄

*设置进程优先级

*分配Csrss进程块

*把新进程的异常处理端口绑定到Csrss中,这样当该进程发生异常时,Csrss将会接收到异常消息

*分配和初始化Csrss线程块

*把线程插入到进程的线程列表中

*把进程插入到Csrss的线程列表中

*显示进程启动光标





5.开始执行初始线程(如果创建时候指定了线程的CREATE_SUSPENDED状态则线程暂时挂起不执行)。到这里进程环境已经建立完毕进程中开始创建的主线程到这里获得执行权开始执行线程。





6.在新进程和线程环境中完成地址空间的初始化(比如加载必须的DLL和库),然后开始到进程入口执行。

到这步实质是调用ldrInitializeThunk来初始化加载器,堆管理器NLS表TLS数组以及临界区结构,并且加载任何必须要的DLL并且用





DLL_PROCESS_ATTACH功能代码来调用各DLL入口点,最后当加载器初始化例程返回到用户模式APC分发器时进程映像开始在用户模式下执行,然后它调用线程启动函数开始执行。





到这里操作系统完成了所有的创建工作,我们写的程序就这样被操作系统调用运行起来了。

Windows操作系统下创建进程的过程的更多相关文章

  1. 【转载】详解CreateProcess调用内核创建进程的过程

    原文:详解CreateProcess调用内核创建进程的过程 昨天同学接到了腾讯的电面,有一题问到了CreateProcess创建进程的具体实现过程,他答得不怎么好吧应该是, 为了以防万一,也为了深入学 ...

  2. 反射实现Model修改前后的内容对比 【API调用】腾讯云短信 Windows操作系统下Redis服务安装图文详解 Redis入门学习

    反射实现Model修改前后的内容对比   在开发过程中,我们会遇到这样一个问题,编辑了一个对象之后,我们想要把这个对象修改了哪些内容保存下来,以便将来查看和追责. 首先我们要创建一个User类 1 p ...

  3. [学习分享] 在Windows操作系统下如何安装RMySQL包

    最近在做股票的高频交易数据分析,需要用到数据库,而我只对MySQL比较熟悉,于是就安装了MySQL.当我安装好了MySQL后,正兴冲冲地准备安装RMySQL包时,问题来了:RMySQL包不支持wind ...

  4. Windows操作系统下远程连接MySQL数据库

    用Eclipse做一个后台项目,但是数据库不想放在本地电脑,于是买了一个腾讯云服务器(学生有优惠,挺便宜的),装上MySQL数据库,但是测试连接的时候,发现总是连接不是上,但是本地数据库可以连接,于是 ...

  5. windows环境下创建 .文件夹

    一.windows环境下创建 .文件夹 1.新建一个文件夹 2.重命名为.properties.(名字前后都加点) 二.windows环境下创建 .文件 1.上面的方法对文件同样适用 2.运行CMD, ...

  6. Windows操作系统下搭建Git服务器和客户端。

    本文将介绍如何在Windows操作系统下搭建Git服务器和客户端.服务器端采用的是Bonobo Git Server,一款用ASP.NET MVC开发的Git源代码管理工具,界面简洁,基于Web方式配 ...

  7. Windows操作系统下SVN无法上传*.o文件

    Windows操作系统下SVN无法上传*.o文件 2017年09月07日 10:14:49 yanlaifan 阅读数:834  摘自:https://blog.csdn.net/yanlaifan/ ...

  8. windows 内核下获取进程路径

    windows 内核下获取进程路径 思路:1):在EPROCESS结构中获取.此时要用到一个导出函数:PsGetProcessImageFileName,申明如下: NTSYSAPI UCHAR *  ...

  9. 关于Windows创建进程的过程

    之前有听到别人的面试题是问系统创建进程的具体过程是什么,首先想到的是CreateProcess,但是对于具体过程却不是很清楚,今天整理一下. 从操作系统的角度来说 创建进程步骤:        1.申 ...

随机推荐

  1. USACO 2009 Open Cow Line /// 队列 oj26220

    题目大意: 输入n,n次操作 操作A:在L(左边)或R(右边)插入一个递增的数 操作D:在L(左边)或R(右边)删除m个数 Sample Input 10A LA LA RA LD R 2A RA R ...

  2. 【POJ】3259 Wormholes

    题目链接:http://poj.org/problem?id=3259 题意:n个农场,m条双向路径,w条单向路径(虫洞).单向虫洞路径是负值.农夫想知道自己能不能看到自己(X). 题解:其实刚开始没 ...

  3. 关于RSA加密和签名的区别与联系

    发现网上对于RSA加密和签名的介绍普遍偏向于使用和概念的说明,今天想说一点不一样的.对于加解密和签名的使用及概念就不再说了,不知道的请自行百度. 签名的本质其实就是加密,但是由于签名无需还原成明文,因 ...

  4. pop&dismiss

    //dismiss到根视图 - (void)dismissToRootViewController{ UIViewController *vc = self; while (vc.presenting ...

  5. 剑指Offer-13:调整数组位置使奇数位于偶数前面

    题目描述: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变.例如给定一个数组 ...

  6. java反射快速入门

    笔记记在了掘金,发现掘金的markdown编辑器比博客园样式要好看不少 https://juejin.im/post/5d4e575af265da03e4674e9f

  7. Django项目:堡垒机(Linux服务器主机管理系统)--03--03堡垒机在Linux系统里记录会话日志02/02

    #main.py #本文件写所有的连接交互动作程序 # ————————————————03堡垒机在Linux系统里记录会话日志 开始———————————————— from Fortress im ...

  8. windows下,根据端口号杀死进程

    1.cmd下,根据端口号查询进程号 C:\>netstat -ano|findstr " 2.根据进程号928,在任务管理器杀死PID为928进程 注意:默认情况下,进程选项卡里没有P ...

  9. 【题解】P1440 均分纸牌

    均分纸牌 题目描述: 有\(N\)堆纸牌,编号分别为\(1,2,-,N\).每堆上有若干张,但纸牌总数必为\(N\)的倍数.可以在任一堆上取若干张纸牌,然后移动. 移牌规则为:在编号为\(1\)堆上取 ...

  10. 同步+TASK异步请求

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...