Python中进程的操作

描述

进程、线程、协程

一、什么是进程

进程是计算机中的程序关于某数据集合的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。

在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向进程设计的计算机结构中,进程是线程的容器。

程序是指令、数据及其组织形式的描述,进程是程序的实体。

狭义定义:进程是正在运行的程序的实例。

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

注意:同一个程序执行两次,就会在操作系统中出现两个进程,所以我们可以同时运行一个软件,分别做不同的事情也不会混乱。

每个进程都有自己独立的一块内存空间,一个进程可以有多个线程,比如在Windows系统中,一个运行的xx.exe就是一个进程。

编译器

二、什么是线程

进程中的一个执行任务(控制单元),负责当前进程中程序的执行。一个进程至少有一个线程,一个进程可以运行多个线程,多个线程可共享数据。

与进程不同的是同类的多个线程共享进程的方法区资源,但每个线程有自己的程序计数器虚拟机栈本地方法栈,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。

编译器

三、进程和线程的区别

根本区别进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位;

内存分配

同一进程的线程共享本进程的地址空间和资源,而进程之间的地址空间和资源是相互独立的;

影响关系

一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。

四、协程

协程(Coroutines)是一种比线程更加轻量级的存在。协程完全由程序所控制(在用户态执行),带来的好处是性能大幅度的提升。

一个操作系统中可以有多个进程;一个进程可以有多个线程;同理,一个线程可以有多个协程。

协程是一个特殊的函数,这个函数可以在某个地方挂起,并且可以重新在挂起处继续运行。一个线程内的多个协程的运行是串行的,这点和多进程(多线程)在多核CPU上执行时是不同的。多进程(多线程)在多核CPU上是可以并行的。当线程内的某一个协程运行时,其它协程必须挂起。

进程微观

一、进程调度

要想多个进程交替运行,操作系统必须对这些进程进行调度,这个调度也不是随机进行的,而是需要遵循一定的法则,由此就有了进程的调度算法。

先来先服务调度算法(先来后到)

短作业优先调度算法(进程的复杂程度不同)

时间片轮转法(分配时间片)

多级反馈队列(分级)

二、进程的并行和并发

编译器

a.并行:并行是指两者同时执行,比如赛跑,两个人都在不停的往前跑;i、(资源够用,比如三个进程,四核的cpu)

b.并发:并发是指资源有限的情况下,两者交替轮流使用资源,比如一座桥(单核cpu)同时只能过一个人,A走一段后,让给B,B用完继续给A,交替使用,目的是提高效率。

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

三、进程的状态

时间片即CPU分配给各个程序的时间,每个线程被分配一个时间段,称作它的时间片,即该进程允许运行的时间,使各个程序从表面上看是同时进行的。

运行程序会创建进程,然后将进程提交到操作系统,操作系统进行进程调度,此时就会进入就绪、运行状态(时间片轮转会导致两种状态相互切换),如果在运行中遇到阻塞事件就会停滞进入阻塞状态(不管是不是阻塞IO,一个线程等待io操作时都会被操作系统挂起,不消耗CPU。),直到等到信号的传递。

编译器

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

阻塞:由于等待某个事件发生而无法执行时,便放弃处理机而处于阻塞状态。引进进程阻塞的事件可有多种,例如,等待I/O完成(IO是输入input输出output的首字母缩写形式)、申请缓冲区不能满足、等待信号等。

同步、异步

同步:

就是一个任务的完成需要依赖另一个任务时,只有等待被依赖的任务完成后,依赖的任务才能完成,这是一种可靠的任务序列。要么成功都成功,失败都失败,两个任务的状态可以保持一致。

 

# 同步  两件事  一件做完再做另外一件

 

异步:

是不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作,依赖的任务也立即执行,只要自己完成了整个任务就算完成了,至于被依赖的任务最终是否完成,依赖它的任务无法确定,所以它是不可靠的任务序列。

 

# 异步  两件事  同时做

 



进程的创建

但凡是硬件,都需要有操作系统去管理,只要有操作系统,就有进程的概念,就需要有创建进程的方式。

对于通用操作系统(跑很多应用程序),需要有系统运行过程中创建或撤销进程的能力,主要分成4种形式创建新的进程:

系统初始化(运行在后台并且只在需要时才唤醒的进程)

一个进程在运行过程中开启了子进程(如nginx开启多进程)

用户的交互请求,而创建一个进程(如双击大家都熟悉的快播)

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

无论哪一种,

新进程的创建都是由一个已近存在的进程执行了一个用于创建进程的系统调用而创建的

进程的结束:正常退出、出错退出、严重错误、被其他进程杀死。

Python中进程的操作

之前我们已经了解了很多进程相关的理论知识,了解进程是什么应该不再困难了,刚刚我们已经了解了,运行中的程序就是进程。所有的进程都是通过它的父进程来创建的。因此,运行起来的Python程序也是一个进程,那么我们也可以在程序中再创建进程。多个进程可以实现并发效果,也就是说,当我们的程序中存在多个进程的时候,在某些时候,就会让程序的执行速度变快。以我们之前所学的知识,并不能实现创建进程这个功能,所以我们就需要借助Python程序中强到大的模块——multiprocessing。

仔细来说,multiprocessing不是一个模块而是Python中一个操作、管理进程的包。之所以叫multi是取自multiple的多功能的意思,在这个包中几乎包含了和进程有关的所有子模块。由于提供的子模块非常多,为了方便大家归类记忆我们分成四个部分:创建进程部分、进程同步部分、进程池部分、进程之间数据共享。

一、multiprocessing.Process模块

Process模块是一个创建进程的模块,语法格式为:
 

Process(target=运行的函数的内存地址,name=自定义进程名称可不写,args=(参数))
编译器

思考:Pycharm、py文件所在的进程、子进程p是同步还是异步?

py文件的运行必须要建立在pycharm的基础上吗?

很明显不用,pycharm只是一个编译器,只是一个更方便我们编程的工具而已,所以肯定是异步的。

问题很多的小明就要问了:那你子进程p要建立在py文件的基础上啊。

那我们检验一下:

编译器

编译器

从运行结果来看,子进程和父进程是同时执行的,所以它们其实也是异步的。

二、Why __name__ =='__main__'  ?

为什么要写if __name_=='__main__': ?

只要是在windows系统上,并且创建子进程,那么就必须写。

原因是不同操作系统之间创建子进程的方式不一样,具体表现为:

Python多进程中,对于子进程的运行机制是:每个子进程中,由于不同的进程之间有独立内存,不会共享,所以每个子进程是通过分别导入所在的脚本模块来实现目标函数的运行的。对于这个机制,有以下两点需要特别注意。

由于每个子进程是通过导入所在脚本的模块实现模块中函数的调用的,所以,为了避免将创建子进程的语句也被导入(因为这样就会造成无限循环创建子进程,这显然是不允许的,因此python禁止了在子进程中再创建子进程,否则会报错),创建子进程的语句必须在if __name__=='__main__'语句之后定义,或者如果创建子进程的语句是定义在一个函数中的,那么这个函数调用必须在if __name__=='__main__'语句之后,这是python多进程中的强制性语法规则。

由于子进程可直接调用的是被导入模块中的属性,因此,子进程中的目标函数应该是被导入的,这样子进程才可以调用到期需要的目标函数,因此,目标函数必须在if __name__=='__main__'语句之前定义,如果是在该语句之后定义,那么由于被导入时这部分是不会被导入的,所以运行时就会报"被导入的主模块没有目标函数属性"这样的错误

三、能否给子进程传参?

试一试不就知道了:

编译器

四、进程间的数据隔离(数据不共享)

编译器

按照我们的理解,num在经过global的声明之后,在全局中其表现形式应该发生了改变,但是我们看结果:

编译器


子进程与父进程的变量的num仍然没有发生改变,说明进程间数据是不共享的,有各自的内存池。

五、如何开启多进程

就...正常...开启...

编译器编译器

六、子进程和父进程的关系

 

编译器

编译器

父进程和子进程的启动是异步的;

父进程只负责通知操作系统启动子进程;

接下来的工作由操作系统接手,父进程继续执行;

父进程的代码执行完毕之后并不会直接结束程序,需要等全部子进程执行完毕;

父进程要负责回收子进程的资源。



审核编辑:刘清

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分