Python基础---进程相关基础

什么是进程

  进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位(是计算机分配资源的最小单位),是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。

  狭义定义: 进程是正在运行的程序的实例(an instance of a computer program that is being executed)

  广义定义: 进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元.

进程的特点: 

  动态性:进程的实质是程序在多道程序系统中的一次执行过程,进程是动态产生,动态消亡的。
  并发性:任何进程都可以同其他进程一起并发执行
  独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位;
  异步性:由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进
  结构特征:进程由程序、数据和进程控制块三部分组成。
多个不同的进程可以包含相同的程序:一个程序在不同的数据集里就构成不同的进程,能得到不同的结果;
但是执行过程中,程序不能发生改变。

进程与程序的区别:

程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念。
而进程是程序在处理机上的一次执行过程,它是一个动态的概念。
程序可以作为一种软件资料长期存在,而进程是有一定生命期的。
程序是永久的,进程是暂时的。

进程的调度

想要实现进程之间交替运行,操作系统就必须对这些进城进行调度,这个调度要遵循一定的法则,由此就产生了进程的调度算法.

  (1) 先来先服务(FCFS)调度算法:   是一种最简单的调度算法,该算法既可用于作业调度,也可用于进程调度。FCFS算法比较有利于长作业(进程),而不利于短作业(进程)。由此可见,FCFS算法适合CPU繁忙型作业,不利于高I/O型操作

  (2) 短作业优先调度算法(SJ/PF):   是指对短作业或短进程优先调度的算法,该算法既可用于作业调度,也可用于进程调度。但其对长作业不利;不能保证紧迫性作业(进程)被及时处理;作业的长短只是被估算出来的。

  (3) 时间片轮转法(Round Robi,RR):  它的基本思路是让每个进程在就绪队列中的等待时间与享受服务的时间成比例.在时间片轮转法中,需要将CPU的处理时间分成固定大小的时间片,例如,几十毫秒至几百毫秒。如果一个进程在被调度选中之后用完了系统规定的时间片,但又未完成要求的任务,则它自行释放自己所占有的CPU而排到就绪队列的末尾,等待下一次调度。同时,进程调度程序又去调度当前就绪队列中的第一个进程。

  在轮转法中,时间片长度的选取非常重要。首先,时间片长度的选择会直接影响到系统的开销和响应时间。如果时间片长度过短,则调度程序抢占处理机的次数增多。这将使进程上下文切换次数也大大增加,从而加重系统开销。反过来,如果时间片长度选择过长,例如,一个时间片能保证就绪队列中所需执行时间最长的进程能执行完毕,则轮转法变成了先来先服务法。时间片长度的选择是根据系统对响应时间的要求和就绪队列中所允许最大的进程数来确定的。

  在轮转法中,加入到就绪队列的进程有3种情况:   第一种是分给它的时间片用完,但进程还未完成,回到就绪队列的末尾等待下次调度去继续执行。第二种情况是分给该进程的时间片并未用完,只是因为请求I/O或由于进程的互斥与同步关系而被阻塞。当阻塞解除之后再回到就绪队列。第三种情况就是新创建进程进入就绪队列。

  (4) 多级反馈队列: 不必事先知道各种进程所需的执行时间,而且还可以满足各种类型进程的需要,因而它是目前被公认的一种较好的进程调度算法。调度算法的实施过程如下所述:

  01. 应设置多个就绪队列,并为各个队列赋予不同的优先级。第一个队列的优先级最高,第二个队列次之,其余各队列的优先权逐个降低。该算法赋予各个队列中进程执行时间片的大小也各不相同,在优先权愈高的队列中,为每个进程所规定的执行时间片就愈小。

  02. 当一个新进程进入内存后,首先将它放入第一队列的末尾,按FCFS原则排队等待调度。当轮到该进程执行时,如它能在该时间片内完成,便可准备撤离系统;如果它在一个时间片结束时尚未完成,调度程序便将该进程转入第二队列的末尾,再同样地按FCFS原则等待调度执行;如果它在第二队列中运行一个时间片后仍未完成,再依次将它放入第三队列,……,如此下去,当一个长作业(进程)从第一队列依次降到第n队列后,在第n 队列便采取按时间片轮转的方式运行。

  03. 仅当第一队列空闲时,调度程序才调度第二队列中的进程运行;仅当第1~(i-1)队列均空时,才会调度第i队列中的进程运行。如果处理机正在第i队列中为某进程服务时,又有新进程进入优先权较高的队列(第1~(i-1)中的任何一个队列),则此时新进程将抢占正在运行进程的处理机,即由调度程序把正在运行的进程放回到第i队列的末尾,把处理机分配给新到的高优先权进程。

进程的并行与并发

并行: 两者同时执行,在同一个时刻,有多个进程在多个CPU上同时进行,能够利用多核,是真正意义上的一对一服务,真正的同时执行任务

并发: 资源有限的情况下,两个进程交替的使用CPU资源,目的是提高效率

串行: CPU将一些进程一个接一个的执行

区别: 并行是从微观上,也就是在一个精确的时间片刻,有不同的程序在执行,这就要求必须有多个处理器。
    并发是从宏观上,在一个时间段上可以看出是同时执行的,比如一个服务器同时处理多个session。

同步异步阻塞非阻塞

 

  在了解其他概念之前,我们首先要了解进程的几个状态。在程序运行的过程中,由于被操作系统的调度算法控制,程序会进入几个状态:就绪,运行和阻塞。

  就绪: 当进程已分配到除CPU以外的所有必要的资源,只要获得处理机便可立即执行,这时的进程状态称为就绪状态。

  执行: 当进程已获得处理机,其程序正在处理机上执行,此时的进程状态称为执行状态。

  阻塞: 正在执行的进程,由于等待某个事件发生而无法执行时,便放弃处理机而处于阻塞状态。引起进程阻塞的事件可有多种,例如,等待I/O完成、申请缓冲区不能满足、等待信件(信号)等。

同步和异步:

  同步: 一个任务的完成需要依赖另一个任务,只有等被依赖的任务执行完毕后,依赖的任务才算完成.很明显的要么都成功,要么都失败.

  异步: 不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作,依赖的任务也立即执行,只要自己的任务完成了整个任务就算是完成了。

阻塞与非阻塞:

  阻塞: 进程中有I/O就是阻塞,比较明显的阻塞情况(input, recv, accept, recvfrom, sleep)

  非阻塞: 进程中没有I/O就是非阻塞,如 setblocking(False)

  同步阻塞: 效率最低.

  同步非阻塞: 效率较低. 想象一下在银行排队办理业务,一边打着电话一边还需要抬头看到底队伍排到你了没有,如果把打电话和观察排队的位置看成是程序的两个操作的话,这个程序需要在两种不同的行为之间来回的切换,效率可想而知是低下的。

  异步阻塞: 异步操作是可以被阻塞住的,只不过它不是在处理消息时阻塞,而是在等待消息通知时被阻塞

  异步非阻塞: 效率更高,还是上面的例子,在银行排队办业务,打电话是自己的事情,叫号是银行工作人员的事情,这个程序没有在两种不同的操作之间进行来回的切换,所以我们自己并没有被阻塞在等待的事情上.

进程的创建和结束

进程的创建

  只要是硬件,都需要有操作系统去管理,只要有操作系统,就有进程的概念,就需要有创建进程的方式,一些操作系统只为一个应用程序设计,比如微波炉中的控制器,一旦启动微波炉,所有的进程都已经存在。

  而对于通用系统则需要有系统运行过程中创建或撤销进程的能力,主要分为4中形式创建新的进程:

  1. 系统初始化(查看进程linux中用ps命令,windows中用任务管理器,前台进程负责与用户交互,后台运行的进程与用户无关,运行在后台并且只在需要时才唤醒的进程,称为守护进程,如电子邮件、web页面、新闻、打印)

  2. 一个进程在运行过程中开启了子进程(如nginx开启多进程,os.fork,subprocess.Popen等)

  3. 用户的交互式请求,而创建一个新进程(如用户双击暴风影音)

  4. 一个批处理作业的初始化(只在大型机的批处理系统中应用)

  无论哪一种,新进程的创建都是由一个已经存在的进程执行了一个用于创建进程的系统调用而创建的。

创建进程:

1. 在Linux中该系统调用是:fork,fork会创建一个与父进程一模一样的副本,二者有相同的存储映像、同样的环境字符串和
同样的打开文件(简单来说,Linux系统中创建进程时会将主进程的所有数据复制一份,存放到进程空间中)
2. 在windows中该系统调用是:CreateProcess,CreateProcess既处理进程的创建,也负责把正确的程序装入新进程。
(简单来说,Windows系统中创建进程,除了完全复制一份之外,还会在子进程空间创建一个数据)

创建子进程:

1.相同的是:进程创建后,父进程和子进程有各自不同的地址空间(多道技术要求物理层面实现进程之间内存的隔离),
任何一个进程的在其地址空间中的修改都不会影响到另外一个进程。
2.不同的是:在UNIX中,子进程的初始地址空间是父进程的一个副本,提示:子进程和父进程是可以有只读的共享内存区的。
但是对于windows系统来说,从一开始父进程与子进程的地址空间就是不同的。

进程的结束

  1. 正常退出(自愿,如用户点击交互式页面的叉号,或程序执行完毕调用发起系统调用正常退出,在linux中用exit,在windows中用ExitProcess)

  2. 出错退出(自愿,python a.py中a.py不存在)

  3. 严重错误(非自愿,执行非法指令,如引用不存在的内存,1/0等,可以捕捉异常,try...except...)

  4. 被其他进程杀死(非自愿,如kill -9)

原文地址:https://www.cnblogs.com/py8318/p/10506445.html