python进程

进程:

程序在计算机中的一次执行过程, 进程是一个动态的过程,占有计算机资源,有一定的生命周期

* 同一个程序不同的运行过程是不同的进程。因为分配的资源和生命周期都不相同

进程的创建流程
1. 用户启动一个程序或者调用接口发起进程创建
2. 操作系统接收用户请求分配计算机资源创建进程
3. 操作系统将一定状态的进程提供给用户使用
4. 用户利用操作系统提供的进程完成任务

进程相关概念

cpu时间片
如果一个进程占有cpu此时我们称为该进程占有cpu时间片。多个进程任务会轮流占有cpu时间片形成并发效果。

进程信息 (process)
PCB (进程控制块):进程创建后会自动在内存生产一个空间存放进程信息。

进程信息 : 进程的ID 进程占有内存的位置,创建时间,创建用户。。。

查看系统该进程信息 :  ps  -aux

PID(process ID) : 在操作系统中每个进程都有唯一的PID值是由系统分配的。

进程特征

* 进程是操作系统分配资源的最小单元
* 每个进程拥有自己独立的运行空间 (虚拟内存空间)
* 进程之间运行相互独立互不影响

进程的状态

    三态
    * 就绪态 : 进程具备执行条件,等待系统分配处理器             资源进入运行态
    * 运行态 : 进程占有cpu处于运行状态

    * 等待态 : 进程暂时不具备运行条件,需要阻塞等待

    五态 (三态基础上增加新建和终止)
    * 新建 : 创建一个新的进程,获取系统资源的过程
    
    * 终止 : 进程执行结束,释放资源的过程

   ps -aux  ---> STAT表示进程状态

   D  等待态 阻塞   不可中断等待态
   S  等待态 睡眠   可中断等待态
   T  等待态 暂停   暂停执行
   R  运行态(就绪态)
   Z  僵尸

   + 前台进程 (在终端运行) 
   <  有较高优先级的进程
   N  较低优先级的进程
   s  会话组
   l  有进程连接

进程的优先级

top 动态查看进程优先级

<  > 进行翻页  q退出

优先级的取值范围 :   -20  ---  19    -20最高

nice : 以指定的优先级运行一个程序

nice   -9   ./while.py  以9的优先级运行
sudo nice   --9   ./while.py  以-9优先级运行

cookie  
首行添加
#!/usr/bin/python3

修改程序权限添加可执行权限
chmod  775  while.py

可以直接指明路径执行
./while.py


父子进程

在系统中除了初始化进程每个进程都有一个父进程,可能有0个或多个子进程。由此形成进程间的父子关系。

便于进程管理,父进程发起创建子进程请求

查看进程树: pstree
查看父子进程PID :  ps  -ajx

要求:
1.什么是进程,进程和程序的区别
2.了解进程的特征和基本概念
3.理解并发并行的区别
4.清楚进程的状态及转换


os.fork 创建进程

pid = os.fork()
功能 : 创建进程
返回值:失败返回一个负数
        成功 : 在原有进程中返回新进程的PID号
             在新进程中返回0

* 子进程会复制父进程全部内存空间包括代码段
* 子进程会从fork的下一句开始执行
* 父进程中fork返回值即为新创建子进程的PID号
* 父子进程不一定谁先执行,执行上互不干扰抢占时间片
* 使用if 语句结构使父子进程执行不同的代码几乎是fork   创建进程的固定结构
* 在子进程中对变量等其他内容的修改,不会影响父进程中   的内容
* 子进程虽然复制父进程内容,但是也有自己的特有属性特征。比如: PID号 PCB 内存区间等

获取进程PID

os.getpid()
功能:获取进程的PID号
返回值 : 返回进程的PID号

os.getppid()
功能:获取父进程的PID号
返回值 : 返回父进程的PID号

进程退出
os._exit(status)
功能 : 退出一个进程
参数 : 进程的退出状态  整数

sys.exit([status])
功能 : 退出一个进程
参数 : 默认为0
        如果传入一个整数则同 _exit()
    传入一个字符串。则在对出时打印该字符串

* sys.exit() 可以通过捕获 SystemExit异常阻止退出

multiprocessing 模块创建进程

1. 需要将要做的事情封装成函数
2. 使用multiprocessing提供的类Process创建进程对象
3. 通过进程对象和Process初始化进程进行进程的设置,绑    定函数
4. 启动进程,会自动执行绑定的函数
5. 完成进程的回收

创建进程对象
Process()
功能: 创建进程对象
参数: target : 要绑定的函数
       name : 给进程起的名称 (默认Process-1)
       args: 元组 用来给target函数位置传参
       kwargs : 字典  用来给target函数键值传参

p.start()
功能 : 启动进程 自动运行terget绑定函数。此时进程被         创建

p.join([timeout])
功能: 阻塞等待子进程退出
参数: 超时时间

* 使用multiprocessing创建进程子进程同样复制父进程的全部内存空间,之后有自己独立的空间,执行上互不干扰
* 子进程也是有自己特有的PID等资源
* 如果不使用join回收可能会产生僵尸进程
* 使用multiprocessing创建子进程,一般父进程功能就是创建子进程回收子进程,所有事件交给子进程完成

Process(target,name,args,kwargs)

name : 给进程起名字
       默认为Process-1 Process-2.....
       p.name 可以获取进程名称

args : 以元组的形式给target函数传参

kwargs : 以字典的形式给对应键的形参传参

进程对象的其他属性方法

p.name  p.start()  p.join() 

p.pid : 创建的新的进程的PID号
p.is_alive()  判断进程是否处于alive状态

p.daemon  默认为False 如果设置为True 则主进程退出时子           进程也会结束

* daemon 属性设置要在start() 前
* 设置daemon为True 则一般不需要加join

cookie
获取文件大小
size = os.path.getsize("./timg.jpeg")

注意:
如果多个子进程拷贝同一个父进程中的对象,则多个子进程使用的是同一个对象(如文件对象,套接字,队列,管道。。。)
如果是在创建子进程后单独创建的对象,则多个子进程各不相同

创建自定义进程类

1. 编写类继承Process
2. 在自定义类中加载父类__init__以获取父类属性,同时可以自定义新的属性
3. 重写run方法,在调用start时自动执行该方法

进程的缺点

进程在创建和销毁的过程中消耗的资源相对较多

进程池技术

产生原因 : 如果有大量的任务需要多进程完成,而任务周期又比较短且需要频繁创建。此时可能产生大量进程频繁创建销毁的情况,消耗计算机资源较大


使用方法 :
1. 创建进程池,在池内放入适当数量的进程
2. 将事件封装函数,放入到进程池
3. 事件不断运行,知道所有放入进程池事件运行完成
4. 关闭进程池,回收进程

from multiprocessing import  Pool

Pool(processes)
功能:创建进程池对象
参数:进程数量
返回 : 进程池对象

pool.apply_async(fun,args,kwds)
功能 : 将事件放入进程池执行
参数: fun 要执行的事件函数
       args  以元组为fun传参
       kwds  以字典为fun传参
返回值 : 返回一个事件对象 通过get()属性函数可以获取
           fun的返回值

pool.apply(fun,args,kwds)
功能 : 将事件放入进程池执行
参数: fun 要执行的事件函数
       args  以元组为fun传参
       kwds  以字典为fun传参
     

pool.close()
功能: 关闭进程池,无法再加入事件

pool.join()
功能 : 回收进程池

pool.map(func,iter)
功能 : 将要执行的事件放入到进程池
参数 : func 要执行的函数
        iter 迭代对象,给func传参
返回值 : 返回 func的返回值列表


进程间通信(IPC)

由于进程间空间独立,资源无法共享,此时在进程间通信就需要专门的通信方法。

进程间通信方法 : 管道  消息队列  共享内存  信号
                   信号量    套接字

管道通信

在内存中开辟一块空间,形成管道结构,多个进程使用同一个管道,即可通过对管道的读写操作进行通信

multiprocessing ---》 Pipe

fd1,fd2 = Pipe(duplex = True)
功能: 创建管道
参数:默认表示双向管道
      如果设置为False则为单向管道
返回值 : 两个管道对象,分别表示管道的两端
          如果是双向管道则均可读写
      如果是单向管道则fd1只读 fd2只写

fd.recv()
功能:从管道读取信息
返回值 :读取到的内容

* 当管道为空则阻塞

fd.send(data)
功能: 向管道写入内容
参数: 要写入的内容

* 管道满时会阻塞
* 可以写入几乎所有的python数据

消息队列

队列 : 先进先出

在内存中开辟队列结构空间,对多个进程可见。多个进程操作同一个队列对象可以实现消息的存取工作。
 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值