【windows操作系统】进程
前⾔
Windows的内部实现也近似于“⼀切皆⽂件”的思想,当然,这⼀切都只在内核⾥才有,下载⼀个WinObj这软件就可以看到,Windows上各种设备、分区、虚拟对象都是挂载到根“\”下的,通过这个树可以访问各种设备、驱动、⽂件系统等等。
Windows与Linux不同的就是把这些对象⼜重新封装了⼀层WindowsAPI,对外以设备、盘符、⽂件等等表现出来,重新封装WindowsAPI的⽬的是为了兼容性,⽽设备、盘符、⽂件这些是为了让普通⽤户更好理解。
所以进程在内核中以数据的形式保存在内存中,也可以看成⼀个⽂件。
进程概述
系统分配资源的最⼩单位!
就是担当分配系统资源(CPU时间、内存等)的基本单位。
cpu分配:⼀个cpu⼀个时间⽚只能执⾏⼀个进程,不同cpu内核并⾏运⾏这个进程中不同的线程。
虚拟内存分配:⼀个进程默认可以分配到和物理内存⼀样⼤⼩的虚拟内存。
进程的运⾏不仅仅需要CPU,还需要很多其他资源,如内存啊,显卡啊,GPS啊,磁盘啊等等,统称为程序的执⾏环境,也就是程序上下⽂。
单CPU进⾏进程调度的时候,需要读取上下⽂+执⾏程序+保存上下⽂,即进程切换。所以进程的创建和销毁都是相对于系统资源,所以是⼀种⽐较昂贵的操作。
进程将内存的地址空间划分为:
代码段(⽂本段 code segment/text segment):保存应⽤的执⾏代码。通常是指⽤来存放程序执⾏代码的⼀块内存区域
数据段(data segment):全局变量,常量,静态变量。例如C#。通常是指⽤来存放程序中已初始化的全局变量的⼀块内存区域。数据段属于静态内存分配。
堆栈段:
堆:存放各种变量数据(new的对象),⼤⼩动态调整。
栈:⼦任务(线程、协程)独⽴存放数据的地⽅(函数调⽤、参数、局部变量等)
进程的虚拟地址空间虽然很⼤,但是它被划分成了很多分区
尹相杰结婚了吗
进程控制块(Processing Control Block),是操作系统核⼼中⼀种数据结构,主要表⽰进程状态,其作⽤是使⼀个程序成为⼀个能够独⽴运⾏的基本单位,并且可以并发执⾏的进程。
进程是运⾏中的程序实例,是操作系统程序动态执⾏的基本单元。为了满⾜操作系统对进程的控制,例如调度,中断,执⾏等操作,操作系统将每个进程描述为⼀个叫做进程控制块(PCB) 的数据结构,在PCB中存储着操作系统对控制⼀个进程所需要的全部信息,可以根据PCB到程序代码,到程序的数据,程序获得的资源等等。所以⼀个进程对于操作系统来说就是⼀个PCB。
在windows中执进程控制块是由 EPROCESS 块来表⽰的。 EPROCESS 块位于内核层之上,它侧重于提供各种管理策略,同时为上层应⽤程序提供基本的功能接⼝。所以,在执⾏体层的进程和线程数据结构中,有些成员直接对应于上层应⽤程序中所看到的功能实体。
EPROCESS结构属于内核的执⾏体层,包含了进程的资源相关信息诸如句柄表、虚拟内存、安全、调试、异常、创建信息、I/O转移统计以及进程计时等。
进程⽣命周期
三状态模型:
阻塞态:等待某个事件的完成(⽐如等待IO数据)。
就绪态:等待系统分配处理器运⾏(随时可以运⾏)。
运⾏态:占有处理器运⾏。
⼀般不太讨论创建态和结束态。5状态和7状态模型很少⽤到
五状态模型
  如果所有进程都做好了准备,操作系统会从未运⾏队列中以轮转的⽅式调度每个进程。但是这⾥有个问题,如果并⾮所有进程都做好了准备呢?也许未运⾏的进程中有些进程正在等待某⼀事件的发⽣,也就是处于阻塞,因此单纯的对所有未运⾏的进程进⾏轮转是不科学的,应该对所有已经就绪的进程进⾏调度。解决这种问题的最好⽅法就是将未执⾏进程队列拆分为两个队列分别是就绪队列和阻塞队列,由此进程的状态由2状态变为了3状态,此外还要增加新建和退出态,这⼗分有必要。改进后的状态模型如下图所⽰。
  运⾏态:进程正在执⾏。
  就绪态:进程做好了准备,随时接收调度。
  阻塞态:进程在等待某些事件的发⽣,在事件发⽣前不能执⾏,如I/O操作。
  新建态:刚刚新建的进程,操作系统还未将其加载⾄内存,通常是PCB已经创建但是还并未加载到内存中的新程序。
  退出态:操作系统从可执⾏进程组中释放的进程。
  新建态与推出态⼗分有必要。在⼀个进程被新建时它并⾮绝对会被调⼊内存,通常是分两步,⾸先创建该进程的PCB,并与之关联,但是此时可能⾯临内存不⾜或者操作系统限制了最⼤进程数导致这个进程还⽆法被调⼊进程,因此该进程被暂时留在新建态,在这个状态的进程PCB已经创建并且加载进内存,但是进程的代码和数据往往还留在外村中等待加载。
  退出态也和新建态同理。当进程因为某些⼈原因要被终⽌时,此时并不直接将其调出内存,⾸先操作系统会停⽌执⾏该进程的代码,但是暂时让其留在内存中,因为某些辅助程序或是⽀持程序会来记录该进程相关数据和信息,此时进程停留在退出态。等相关程序收集完所需信息后,再将其所有数据从内存中移除。
  关于阻塞,就绪和运⾏三种状态的转换更为普遍和便于理解。操作系统从就绪队列中调度某个进程进⼊运⾏态运⾏,当时间⽚结束后操作系统将其放回就绪态执⾏其他进程,如果在执⾏期间进程必须
等待某些事件,便将其放⼊阻塞态,然后调度其他进程执⾏。当该进程等待的事件完成后操作系统则将其放回就绪态等待调度。
  但是此时⼜有⼀个问题,如果所有阻塞进程放在同⼀个阻塞队列中,当⼀个事件完成后操作系统不得不扫描整个队列到那些等待该事件的进程然后将其放进就绪队列中,这样的效率⼗分低下,因此通常是为每⼀个事件创建⼀个阻塞队列。同理当按照优先级进⾏调度时,也会将优先级相同的进程放进⼀个就绪队列,避免扫描等低效的做法,这是典型的⽤空间换时间的做法。
七状态模型
  在介绍七状态模型前,我们思考⼀个问题,三个基本状态(就绪,运⾏和阻塞)的所有进程都必须存储在内存中,此时就可能出现⼀种情况,即所有进程都处于阻塞态,没有就绪状态的进程,此时⼜开始了处理器的空转,处理器没办法执⾏进程只能开始等待进程从阻塞态恢复就绪态,并且加⼊此时⼜有新的进程处于新建态,由于内存不⾜,处于新建态的进程也没办法进⼊内存⽆法执⾏,这是⼀个⼗分致命的处理器空转问题,解决这个问题有两个⽅法:扩⼤内存,很显然成本太⾼了;将阻塞态的进程暂时调出内存放回磁盘,来让新建态的进程有⾜够内存进⼊就绪态开始处理器的调度和运⾏。
  但是在将⼀个阻塞态进程挂起后,操作系统可以选择接纳⼀个新建态进程进⼊就绪队列,也可以选择将⼀个之前挂起的进程恢复就绪态,并且为了减少操作系统的负载操作系统更倾向于后者。但是处
于挂起的进程也可能还并未接触阻塞,将⼀个阻塞进程放回内存没有任何意义,于是更好的⽅法是将挂起区分为两个状态即就绪/挂起态和阻塞/挂起态,这样每次操作系统就只需要考虑是否应该把进程从就绪/挂起态换回就绪态即可。完整的七状态模型如下:
  阻塞/挂起态:进程在外存中并等待⼀个事件。
  就绪/挂起态:进程在外存中,但只要载⼊内存即可开始运⾏。
  并且操作系统允许进程从就绪变为就绪/挂起态,或从阻塞/挂起态变更为阻塞态,只是这样做的意义不⼤,因此并不会这样做。
  导致进程被挂起的事件有以下⼏种:
  1、交换。为了释放内存空间。
  2、其他OS原因。操作系统可能会挂起后台进程或者⼯具进程,或挂起可能会导致问题的进程。歌曲 曹操
  3、交互式⽤户请求。⽤户希望挂起⼀个进程来进⾏调试。
  4、定时。进程可被周期性的执⾏,并在等待下⼀个时间间隔时挂起。
黄圣依个人简历
  5、⽗进程请求。⽗进程可能希望挂起后代进程的执⾏,以检查或修改挂起的进程。
进程调度算法
抢占式调度
在“抢先式调度”中,⼤多数任务都分配有其优先级。有时,即使较低优先级的任务仍在运⾏,在另⼀个较低优先级的任务之前运⾏具有较⾼优先级的任务也很重要。较低优先级的任务会保留⼀段时间,并在较⾼优先级的任务完成执⾏时恢复。
⾮抢占式调度
在这种调度⽅法中,已将CPU分配给特定的进程。使CPU保持繁忙的进程将通过切换上下⽂或终⽌来释放CPU。这是可⽤于各种硬件平台的唯⼀⽅法。那是因为它不需要抢先式调度之类的特殊硬件(例如计时器)。
先来先服务调度算法
最短作业优先调度算法
⾼响应⽐优先调度算法
时间⽚轮转调度算法
最⾼优先级调度算法
多级反馈队列调度算法
进程间通信的⽅式
1. 管道(pipe)及有名管道(named pipe):管道可⽤于具有亲缘关系的⽗⼦进程间的通信,有名管道除了具有管道所具有的功能外,它还允许⽆亲缘关
系进程间的通信。
2. 信号(signal):信号是在软件层次上对中断机制的⼀种模拟,它是⽐较复杂的通信⽅式,⽤于通知进程有某事件发⽣,⼀个进程收到⼀个信号与处理器
收到⼀个中断请求效果上可以说是⼀致的。
3. 消息队列(message queue):消息队列是消息的链接表,它克服了上两种通信⽅式中信号量有限的缺点,具有写权限的进程可以按照⼀定的规则向消
息队列中添加新信息;对消息队列有读权限的进程则可以从消息队列中读取信息。
4. 共享内存(shared memory):可以说这是最有⽤的进程间通信⽅式。它使得多个进程可以访问同⼀块内存空间,不同进程可以及时看到对⽅进程中对共
享内存中数据的更新。这种⽅式需要依靠某种同步操作,如互斥锁和信号量等。
5. 信号量(semaphore):主要作为进程之间及同⼀种进程的不同线程之间的同步和互斥⼿段。
6. 套接字(socket):这是⼀种更为⼀般的进程间通信机制,它可⽤于⽹络中不同机器之间的进程间通信,应⽤⾮常⼴泛。
进程特征
动态性进程既然是进程实体的执⾏过程,因此进程是有⼀定的⽣命期。⽽程序只是⼀组有序指令的集合,并放在某种介质上,本⾝⽆运⾏的含义,因此程序是个静态的实体。
并发性(concurrence)
并⾏性是指两个或者多个事件在同⼀时刻发⽣,这是⼀个具有微观意义的概念,即在物理上这些事件
是同时发⽣的;⽽并发性是指两个或者多个事件在同⼀时间的间隔内发⽣,它是⼀个较为宏观的概念。
在多道程序环境下,并发性是指在⼀段时间内有多道程序在同时运⾏,但在单处理机的系统中,每⼀时刻仅能执⾏⼀道程序,故微观上这些程序是在交替执⾏的。应当指出,通常的程序是静态实体,它们是不能并发执⾏的。为了使程序能并发执⾏,系统必须分别为每个程序建⽴进程。进程,⼜称任务,简单来说,是指在系统中能独⽴运⾏并作为资源分配的基本单位,它是⼀个活动的实体。多个进程之间可以并发执⾏和交换信息。⼀个进程在运⾏时需要运⾏时需要⼀定的资源,如 cpu,存储空间,及i/o设备等。在操作系统中引⼊进程的⽬的是使程序能并发执⾏。
独⽴性这是指进程实体是⼀个能独⽴运⾏的基本单位,同时也是系统种独⽴获得资源和调度的基本单位。
异步性(asynchronism)  在多道程序设计环境下,允许多个进程并发执⾏,由于资源等因素的限制,通常,进程的执⾏并⾮“⼀⽓呵成”,⽽是以“⾛⾛停停”的⽅式运⾏。内存中每个进程在何时执⾏,何时暂停,以怎样的⽅式向前推进,每道程序总共需要多少时间才能完成,都是不可预知的。或者说,进程是以异步的⽅式运⾏的。尽管如此,但只要运⾏环境相同,作业经过多次运⾏,都会获得完全相同的结果,因此,异步运⾏⽅式是允许的。
张婉悠厕所门种子
结构特征从结构上看,进程实体是由程序段、数据段及进程控制块三部分组成。迪奥系列
(进程控制块(PCB):进程控制块是进程实体的⼀部分,它记录了操作系统所需要的、⽤于描述进程情况及控制进程运⾏所需的全部信息。os 是根据PCB来对并发执⾏的进程进⾏控制和管理的)
多进程
在同⼀个时间⾥,同⼀个计算机系统中如果允许两个或两个以上的进程处于运⾏状态,这便是多任务(多进程)。现代的操作系统⼏乎都是
多进程操作系统,能够同时管理多个进程的运⾏。多进程带来的好处是明显的。但是多进程对于系统的资源要求甚⾼,资源浪费也⽐较严重。应⽤多进程场景最多的是windows系统,例如同时打开运⾏软件,每个软件打开相当于运⾏⼀个进程。
进程调度
由于CPU同时刻只能执⾏⼀个进程,如果我们不加以控制的话,⼀个进程可能使⽤CPU直到运⾏结束,于是出现了操作系统调度器,⽽进程也成为了调度单位。
进程上下⽂
进程的运⾏不仅仅需要CPU,还需要很多其他资源,如内存啊,显卡啊,GPS啊,磁盘啊等等,统称为程序的执⾏环境,也就是程序上下⽂。
进程并发
 在这⾥就出现了并发的概念,调度器切换CPU给不同进程使⽤的速度⾮常快,于是在使⽤者看来程序是在同时运⾏,这就是并发,⽽实际上CPU在同⼀时刻只在运⾏⼀个进程。
单个CPU只有并发,没法并⾏。
进程同步
1、进程同步的基本概念
多道程序环境下,进程是并发执⾏的,不同进程间存在着不同的相互制约关系。为了协调进程之间的相互制约关系,达到资源共享和进程协作,避免进程之间的冲突,引⼊了进程同步的概念。
(1)临界资源
多个进程可以共享系统中的各种资源,但其中许多资源⼀次只能为⼀个进程所使⽤,我们把⼀次只允
许⼀个进程使⽤的资源成为临界资源。对临界资源的访问,必须互斥的进⾏。每个进程中,访问临界资源的那段代码成为临界区。
为了保证临界资源的正确使⽤,可以把临界资源的访问过程分为四个部分。
1)进⼊区。为了进⼊临界区使⽤临界资源,在进⼊去要检查可否进⼊临界区。
2)临界区。进程中访问临界资源的那段代码。
3)退出区。将正在访问临界区的标志清除。
4)剩余区。代码中的其余部分。
do {
entry section;
critical section;
exit section;地震怎么办
remainder section;
}while (true)
(2)同步
同步已成为直接制约关系,它是为完成某种任务⽽建⽴的两个或多个进程。这些进程因为需要在某些位置上协调他们的⼯作次序⽽等待、传递信息所产⽣的制约关系。进程间的直接制约关系就是它们之间的相互合作。
(3)互斥
互斥亦称间接制约关系。当⼀个进程进⼊临界区使⽤临界资源时,另⼀个进程必须等待,当占⽤临界资源的进程退出临界区后,另⼀个进程才允许去访问此临界资源。
实现临界区互斥的基本⽅法
在进⼊区设置和检查⼀些标志来表名是否有进程在临界区中,如果已有进程在临界区,则在进⼊区通过循环检查进⾏等待,进程离开临界区
后则在退出区修改标志。
进程和线程之间的区别
  这是⼗分常见的问题,在此做同⼀归纳和梳理:
  1、进程是资源分配的基本单位,线程是处理器调度的基本单位。
  2、同⼀进程内线程共享进程状态和资源,例如数据段,代码段,I/O信息等。但是每个线程内也有独⽴的数据,每个线程都拥有属于⾃⼰的栈,线程属性信息存在线程控制块中,例如上下⽂数据,线程状态,调度信息等。
  3、线程是轻量级进程,因此创建和销毁所消耗的系统资源更少,更快。
  4、同⼀进程内线程切换所消耗的资源相⽐进程切换更少且更快。
  5、同⼀进程内线程共享⼤部分数据因此通信起来更加⽅便,⽆需借助内核。