进程知多少?

文章首发:进程知多少?编程

Java 多线程系列文章第 1 篇设计模式

要讲线程,通常都得讲一讲进程,进程是何方神圣呢?下面来简单介绍一下。微信

先经过任务管理器看看 Windows 系统下的进程。网络

从图片来看,每个进程都占有 CPU、内存、磁盘、网络等资源。站在操做系统的角度,进程是分配资源的基本单位,也是最小单位多线程

进程为何出现?

引入进程的目的:为了使多个程序能并发执行,以提升资源的利用率和系统的吞吐量。怎么理解这句话呢?一个程序在运行过程当中会涉及不少操做,利用 CPU 计算、经过磁盘 IO 进行数据传输等等,咱们知道当程序在进行磁盘 IO 的时候,由于速度问题,会比较慢,所在在这个过程当中 CPU 会空闲下来,这会形成资源的浪费,正由于引入进程,在 A 进程进行磁盘 IO 的时候,会让出 CPU 给 B 进程,合理地利用了 CPU 资源,使得程序之间能够并发执行。并发

从 CPU 角度,执行过程是这样子的:CPU 一直在负责执行指令,进程之间互相竞争 CPU 资源,下图有 A 和 B 进程,在一个时间点,CPU 只执行一个进程的指令,由于 CPU 运行很快,因此在我们看起来,像是多个进程在同时跑。这就是进程带来的好处:提升资源利用率,并发地执行多个程序socket

固然引入进程也不是有益无害,它增长了系统的时间空间开销。空间开销这个好理解,进程有本身的组成部分(下面会讲),这个就占用了空间。时间开销则是进程切换须要时间。学习

进程的组成

进程由 3 个部分组成,分别是程序代码数据集、栈进程控制块(Process Control Block)操作系统

各自的做用以下:

  1. 程序代码:描述了进程须要完成的功能。
  2. 数据集、栈:程序在执行时所须要的数据和工做区。
  3. 进程控制块:包含进程的描述信息和控制信息,它是进程存在的惟一标识。

如何竞争资源(调度算法)

进程之间须要竞争资源,通常都是竞争 CPU 资源,由于 CPU 运行速度太快了,其余介质都赶不上。有了竞争就须要有规则,就像游戏同样,每一个游戏都须要规则,不一样规则会有不一样的侧重点,这个看过“最强大脑”这个节目的朋友就很是清楚,每道题都有不一样的考核侧重点,有些是侧重空间思惟、有些侧重逻辑推算等等。下面咱们就简单地一一讲解竞争资源的游戏规则。

FCFS

First In First Out(先来先服务):最早进入就绪队列的进程,先运行,运行到完成或者阻塞时,再从新调度。通常状况下,这种调度算法会和优先级策略结合,好比每一个优先级一条队列,每条队列中的调度都使用 FCFS。

特色:简单、比较偏于长进程、相对于其余调度算法平均周转时间长

RR

Round Robin(轮转):进程按提交顺序存在就绪队列,依次轮流占用 CPU 资源,运行一段固定的时间,时间到后若是还没执行完,就继续进入就绪队列队尾,排队等待下次执行。

特色:公平、对进程的响应时间较短

SPN

Shortest Process Next(最短进程优先):将预期占用运行时间最短的进程优先执行,直到运行完成或阻塞时,再从新调度。

特色:有利于短进程

SRT

Shortest Remaining Time(最短剩余时间优先):新进程进来时,若是新进程的预计运行时间比当前进程的剩余运行时间更短,就抢占当前进程,

特色:有利于短进程,和 SPN 的差异在于抢占这个一点,由于抢占,因此效率会比 SPN 好一些。

HRRN

Highest Response Ratio Next(最高响应比优先):当前运行的进程完成或者阻塞时发生调度,每次调度前,计算全部就绪进程的响应比,响应比高的进程优先运行。

响应比公式以下所示:

特色:有利于短进程服务时间相同的进程,先来的服务会优先执行长进程由于在等待的过程当中,优先级愈来愈高,因此不会一直不执行

FB

Feedback (反馈):由多个就绪队列组成的反馈机制,它有以下规则:

  1. 在同一个队列的进程,按 FCFS 算法调度,最后一个就绪队列按 RR 算法调度;
  2. 优先级越高的队列,时间片越小;
  3. 进程在一个时间片内未运行完,则降到下一个队列末尾;
  4. 只有上级队列无就绪进程时,才运行本级就绪队列,本级就绪队列无进程时,才运行下级就绪队列,以此类推

进程执行过程以下图所示

特色:短进程有很是大的优点,排在前面的队列都是时间较短的

以上就是几个抢占资源的调度算法的说明。

进程状态

上面咱们讲到,进程之间是在竞争资源,获得资源就运行,没获得就等待,这个须要有状态来维护,像不少系统同样,须要一个状态机。

三态图

三态图也是描述进程状态最简单最基础的图,它包含了进程的最基本的 3 个状态,分别是:就绪态、运行态和阻塞态。

Read(就绪态):进程已获得除 CPU 之外的其余所需资源。
Running(运行态):进程的指令正被执行。
Blocked(阻塞态):进程正等待资源或某事件发生。

进程三态图

就绪态的进程在被调度的时候,进入了运行态,若是时间片运行完或者有更高级别进程抢占资源,则变成就绪态等待再次被调度;若是发生事件(好比 IO 事件),则从运行态转到阻塞态,进入阻塞态的进程只能等待事件解除从新进入就绪态

五态图

基于三态图,新增了 2 个状态,分别是:新建态和退出态。

New(新建态):进程正被建立。分配内存后将被设为就绪态。

Exit(退出态):进程已正常结束或出现异常结束。回收资源。

进程五态图

新进程刚建立尚未分配资源的时候是新建态,等到分配了资源,被加载后就进入就绪态。当进程运行完后,就从运行态进入退出态

七态图

基于五态图,新增了 2 种挂起态,分别是就绪挂起态和阻塞挂起态。

就绪挂起态:另叫外存就绪态。因为内存容量有限,将原位于内存的就绪进程转存到外存(磁盘)上。

阻塞挂起态:另叫外存阻塞态。同样由于内存容量有限,将原位于内存的阻塞进程转存到外存(磁盘)上。

七态图

咱们能够看出,图中新增了解除挂起的状态转换过程,通常是因为挂起进程优先级比较高或者内存空间足够,把位于外存(磁盘)的进程转存到内存中。

进程关系

进程之间其实比较独立,好比咱们在平常使用的 QQ 和微信,它们运行起来的进程有什么关系么?其实除了互相竞争资源以外,没有任何关系。

父子关系

虽然上面说的进程之间没有关系,可是有一个特殊关系须要讲,就是父子关系

先作个试验,验证进程的父子关系。操做步骤:

  1. 打开 CMD 命令行程序,将当前的窗口设置为 Father,在 Father 窗口经过命令start cmd启动另外一个 CMD 命令行程序;
  2. 将新开的 CMD 命令行程序的窗口设置为 Son,在 Son 窗口经过命令start cmd启动另外一个 CMD 命令行程序;
  3. 将新开的 CMD 命令行程序的窗口设置为 Grandson。

操做过程以下图所示。

经过 ProcessExplorer 能够很清晰看到这 3 个 CMD 进程之间的关系。(想要 ProcessExplorer 插件能够经过百度网盘下载连接:https://pan.baidu.com/s/19531gf5tD_of1CWxpFR9Dg 提取码:qhc6)

咱们看到 Father、Son、Grandson 三个进程呈现出咱们预料中的树形。那么什么是父子进程呢?简单的说就是在进程中建立出新的进程,这个新的进程就是子进程,一个进程能够有多个子进程,可是只能有一个父进程。在 Unix 系统中,父进程经过调用 fork() 建立子进程,父子进程有以下特色:

  1. 父、子进程并发执行;
  2. 父、子进程共享父进程的全部资源;
  3. 子进程复制父进程的地址空间,甚至有相同的正文段和程序计数器 PC 值;
  4. 利用写时复制(Copy On Write)技术减小没必要要的复制:fork 时父子共用父空间,当一方试图修改时才复制。

这里重点讲一下Copy On Write,使用了这个技术,父进程建立子进程的时候不会复制全部数据到子进程,省了复制的时间以及减小了大量的内存。这个复制不是必要的,由于若是应用程序在进程复制以后当即加载新程序,那以前的复制工做就是浪费时间和内存了。

讲了进程父子关系,就免不了提一下僵尸进程孤儿进程,下面分别介绍一下。

僵尸进程

僵尸进程:子进程退出后,父进程没有调用 wait 或 waitpid 获取子进程的状态信息,子进程的进程描述符仍保存在系统中,这种进程叫僵尸进程。

僵尸进程的危害:僵尸进程会一直占用进程号,系统能使用的进程号又是有限的,若是有大量的僵尸进程,会由于没有可用进程号致使没法建立新的进程。

孤儿进程

孤儿进程:父进程结束退出,而它的子进程还在运行,这时的子进程就叫作孤儿进程。孤儿进程就被 init 进程(进程号为 1)收养,init 进程将对孤儿进程完成状态收集工做。

孤儿进程没有危害,由于被 init 进程托管了,init 进程会处理孤儿进程的收集工做。

执行模式

指令分为特权指令(只能由操做系统内核使用的指令)和非特权指令(只能由用户程序使用的指令),由于指令有特权和非特权之分,因此 CPU 也分为 2 种执行模式:系统态(能够执行全部指令,使用全部资源以及改变 CPU 状态)和用户态(只能执行非特权指令)。

CPU 的系统态和用户态之间的切换。

进程间通信

当进程之间须要数据传输、共享数据时,进程间就须要互相通信,通信方式有以下几种,这里只是简单归纳一下,不展开讲,咱的重点在于多线程,进程我们简单了解一下就能够,感兴趣的同窗能够根据要点进行深刻学习。

管道(Pipe)

管道是半双工通信,数据是单向流动,要创建进程间互相通信,则须要 2 个管道,这种通信方式只能在亲戚关系的进程间使用,好比父子进程。

流管道(Flow Pipe)

流管道是管道进化来的,数据再也不是单向流动,能够双向流动,可是依旧是只能在亲戚关系的进程间使用。

有名管道(Named Pipe)

有名管道提供了新的功能,就是给管道设置名字,它改善了上面 2 种管道通信方式,支持了非亲戚关系的进程通信。

信号量(Semophore)

信号量至关于计数器,利用它来控制多个进程访问共享资源,当一个进程A在访问共享资源时,信号量防止其余进程来访问,只有当进程A不访问共享资源了,其余进程才能访问。

信号(Signal)

信号能够在任什么时候候发给某一进程,不须要知道该进程当前的状态,若是对方进程未执行,信号会存在内核中,直到进程执行后传递给它;若是对方进程是阻塞,则信号会延迟传递,等到对方进程阻塞取消后才传递给它。

消息队列(Message Queue)

消息队列是存放在内核中的链表,能够有多个进程对这个链表进行写入和读取,它解决了信号传递信息少、管道只能传输无格式字节流和缓冲区大小受限的缺点。目前有 POSIX 消息队列和 System V 消息队列。

共享内存(Shared Memory)

共享内存即为一段能被其余进程访问的内存,多个进程访问同一个内存,达到了通信的效果。

套接字(Socket)

套接字就是咱们网络编程里面的那个套接字,能够经过网络也能够在本机进行通讯,它的好处在于能够跨主机进行通讯。

总结

总的来讲,进程是程序在一个数据集上的一次执行过程,它就是程序运行起来的表现。这是咱们学习多线程的开篇,但愿经过这篇文章,让你们简单地了解进程是什么,后面咱们再来深刻了解多线程。

推荐阅读

设计模式看了又忘,忘了又看?

公众号后台回复『设计模式』能够获取《一故事一设计模式》电子书

以为文章有用帮忙转发&点赞,多谢朋友们!

LieBrother

相关文章
相关标签/搜索