多任务编程
通过应用程序利用多个计算机核心达到多任务同时执行的目的,以此来提升程序执行效率
一、多进程
- 进程:程序在计算机中一次执行的过程;是一个动态的过程,占有cpu内存的计算机资源,有一定的生命周期
- 程序:是一个静态的描述,不占有计算机资源
- 同一个程序,每一次执行都是不同的进程。因为分配的计算机资源不同
进程的创建流程
- 用户空间运行程序发起进程创建申请
- 调用操作系统内核接口创建进程
- 分配计算机资源,确定进程状态
- 将新的进程提供给用户使用
多个进程如何占用计算机cpu
- 一个内核同一时刻只能运行一个任务
- 多个进程对内核资源进行争夺,操作系统决定哪个进程占有计算机核心
- 占有计算机核心的进程,我们称为该进程占有cpu的时间片
进程有哪些信息,如何保存
- PCB(进程控制块):在l/unix系统中进程创建后,会在内存开辟一块空间存放进程相关信息,称为PCB
- 查看进程信息 ps -aux
- 信息:用户 PID 占有内存 优先级 等
- PID:在操作系统中进程的唯一标识,是大于0的整数,由系统自动分配
进程特征
- 进程是操作系统资源分配的最小单位
- 每个进程单独占有4G虚拟内存
- 进程之间相互独立,运行不受影响
进程的状态
三态
- 就绪态
进程具备运行条件,等待系统分配处理器运行 - 运行态
进程占有cpu,处于运行状态 - 等待态
又称为阻塞态,睡眠态,指进程暂时不具备运行条件,需要阻塞等待(sleep,accept,…,)
五态
- 新建态
创建一个进程,获取资源,直接表现为运行一个程序,或者在程序中创建新的进程 - 就绪态
进程具备运行条件,等待系统分配处理器运行 - 运行态
进程占有cpu,处于运行状态 - 等待态
又称为阻塞态,睡眠态,指进程暂时不具备运行条件,需要阻塞等待(sleep,accept,…,) - 终止态
进程执行结束,资源回收过程
ps -aux —>STAT 表示进程状态
- D 等待态 (不可中断等待)
- S 等待态 (可中断等待)
- T 等待态 (暂停)
- R 运行态
- Z 僵尸态
- +前台进程(不带+号即为后台进程)
- < 高优先级
- N 低优先级
- l 有进程链接
- s 会话组
进程的优先级
- 优先级决定了一个进程的执行权限和占有资源的优先程度
- top : 动态查看当前运行的进程的状态 q退出 <>上下翻页
- Linux 中优先级范围 -20----19 -20最高
- 用户程序默认优先级为
- nice : 以指定的优先级运行程序
e.g. nice -9 ./while.py 以9的优先级运行此程序
sudo nice --9 ./while.py 以-9的优先级运行此程序 - renice : 改变某个进程的优先级
e.g. renice 2 PID
/usr/bin/env: ‘python\r’: No such file or directory
1、路径切到demo.py下面,这里demo.py是所运行的python文件
2、用vim打开demo.py
3、从键盘输入冒号:,再输入set ff,回车,显示为dos格式
4、从键盘输入冒号:再输入set ff=unix , 回车
5、从键盘输入冒号:,再输入wq, 回车
父子进程(proces)
在系统中除了初始化进程外,其他进程都有一个父进程,可能有多个子进程。
- 进程树 pstree
要求
1.什么是进程,进程的特征
2.进程的状态,每种状态怎么回事,转换
3.进程和线程的区别
import os
os.fork()
"""
功能:创建一个新的进程
参数:无
返回值:失败返回一个负数 -1,成功 0 在子进程中fork的返回值,>0的正整数(新的进程的PID)在父进程中的返回值
"""
- 父进程中fork之前的内容子进程同样会复制,但父子进程空间独立,fork之后的修改不会影响到对方
- 父子进程在执行上互不影响,谁先执行,谁后执行完全不确定
- 子进程虽然复制父进程的空间,但是有自己的特性,比如自己的PID,进程PCB,进程栈空间等
进程相关函数
os.getpid() #获取当前进程的PID号
os.getppid() #获取当前进程父进程的PID号
os._exit(status) #结束一个进程,参数表示进程的结束状态,是一个整数
sys.exit([status]) #结束一个进程,抛出异常,传入一个正整数表示结束状态,传入一个字符串表示结束打印
孤儿进程
父进程先于子进程退出,此时子进程变成孤儿进程
- 孤儿进程会被系统指定的进程所“收养”,即该进程成为孤儿进程新的父进程。在孤儿进程退出时,“继父”会进行处理,不会使其成为僵尸
僵尸进程
子进程先于父进程退出,但是父进程没有处理子进程的退出状况,子进程就会成为僵尸进程
- 僵尸进程会滞留PCB的部分信息在内存中,大量的僵尸进程会消耗系统资源,所以应该尽量避免僵尸进程的产生
- 如何避免僵尸进程的产生?
- 让父进程先退出(不好控制)
- 让父进程处理子进程的退出
*使用wait或者waitpid函数
*使用信号处理os.wait()#等待子进程的退出进行处理,参数无,返回一个二元元组,(子进程PID,进程退出状态) os.waitpid(pid,option)#处理子进程的退出,pid(-1表示等待任意的子进程退出,>0表示等待相应pid号的子进程),option(0表示阻塞等待,WNOHANG表示非阻塞等待),返回值同上
- 创建二级子进程
父进程创建子进程后等待子进程退出,子进程创建二级子进程后马上退出,二级子进程成为孤儿,让父进程和二级子进程处理具体事件
multiprocessing 模块创建进程 标准库
- 需要将事件封装为函数
- 使用multiprocessing提供的类创建新进程
- 新的进程和对应的函数相关联,进程启动会自动执行函数,完成事件
- 进程回收
创建子进程类
multiprocessing.Process()
#功能:创建子进程
#参数:name,给创建的进程起一个名字,默认process-1
#target,目标函数
#args,元组,要给函数传递的参数 位置
#kwargs,字典,要给函数传递的参数 键值
#进程对象属性函数
p.start()
#功能:启动子进程,此时进程真正创建
p.join([timeout])
#功能:阻塞等待回收相应的子进程
#参数:默认为阻塞,timeout为超时时间
#p的其他属性
#p.name 进程名称
#p.pid 创建的进程的PID号
#p.is_alive() 进程状态
#p.daemon 默认值为False,表示主进程结束后不影响子进程的执行,如果设置为True,则主进程执行完毕所有的子进程一同退出
#1.设置必须在start()前
#2.一般使用daemon=True时不加join
#3.该属性不是Linux或者Unix系统中所说的守护进程设置
守护进程
- 生命周期长,随系统创建随系统销毁
- 不受前端控制,后台运行
- 操作系统进程,或者是自动化运行进程居多
cookie:
size = os.path.getsize(‘file’) 获取一个文件的大小
创建自己的进程类
from multiprocessing import Process
import time
class ClockProcess(Process):
def __init__(self, value):
self.value = value
super().__init__()
# 在自定义的进程类中重写父类的这个方法
def run(self):
n = 5
while n > 0:
print("The time is {}".format(time.ctime