栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python之进程

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python之进程

文章目录
      • 1、进程理论
        • 1.1、程序和进程
        • 1.2、串行、并发、并行
        • 1.3、进程的创建
        • 1.4、进程的终止
        • 1.5、进程运行的三种状态
          • 1.5.1、就绪态
          • 1.5.2、运行态
          • 1.5.3、阻塞态
        • 1.6、优化程序效率的核心法则
        • 1.7、同步和异步
        • 1.8、阻塞非阻塞
      • 2、进程
        • 2.1、multiprocessing模块
        • 2.2、Process类
          • 2.2.1、创建进程的类
          • 2.2.2、参数
          • 2.2.3、方法
          • 2.2.4、属性
        • 2.3、Process类的使用
        • 2.4、开启进程的两种方式
          • 2.4.1、方式一
          • 2.4.2、方式二
        • 2.5、进程间数据相互隔离
        • 2.6、进程调度
        • 2.7、僵尸进程和孤儿进程
        • 2.8、进程对象及其他方法
        • 2.9、守护进程

1、进程理论 1.1、程序和进程
1、程序
   程序就是一堆代码文件,计算机中安装的应用程序在没有打开/运行之前,称之为程序,他是存在于计算机硬盘之上的,换而言之,程序是“死的”

2、进程(进程是操作系统最核心的概念)
   计算机中运行的应用程序在打开/运行之后,称之为进程,顾名思义,进程即正在执行的一个过程,换而言之,程序是“活的”,进程是对正在运行程序的一个抽象。
1.2、串行、并发、并行
串行: 一个运行完毕再运行下一个
并行: 多个进程是真正意义上一起运行
并发: 看起来是同时运行的,本质还是一个个的运行
进程彼此之间的内存空间隔离,而且是物理隔离

并行肯定属于并发
单核计算机肯定不能实现并行,但是可以实现并发

1.3、进程的创建
windows: CreateProcess
linux: fork
1.4、进程的终止
1. 正常退出(自愿,如用户点击交互式页面的叉号,或程序执行完毕调用发起系统调用正常退出,在linux中用exit,在windows中用ExitProcess)
2. 出错退出(自愿,python a.py中a.py不存在)
3. 严重错误(非自愿,执行非法指令,如引用不存在的内存,1/0等,可以捕捉异常,try...except...)
4. 被其他进程杀死(非自愿,如kill -9)
1.5、进程运行的三种状态 1.5.1、就绪态
进程已获得除CPU外的所有必要资源,只等待CPU时的状态。一个系统会将多个处于就绪状态的进程排成一个就绪队列
1.5.2、运行态
进程已获CPU,正在执行。单处理机系统中,处于执行状态的进程只有一个;多处理机系统中,有多个处于执行状态的进程
1.5.3、阻塞态
正在执行的进程由于某种原因而暂时无法继续执行,便放弃处理机而处于暂停状态,即进程执行受阻(这种状态又称等待状态或封锁状态)

ps: 通常导致进程阻塞的典型事件有: 请求I/O,申请缓冲空间等。

一般,将处于阻塞状态的进程排成一个队列,有的系统还根据阻塞原因不同把这些阻塞集成排成多个队列。

1.6、优化程序效率的核心法则
降低IO操作(硬盘IO、网络IO)

优化方案:
内存 => 本地硬盘 => 网络IO
1.7、同步和异步
描述的是任务的提交方式
同步: 任务提交之后,原地等待任务的返回结果,等待的过程中不做任何事(干等)
  	程序层面上表现出来的感觉就是卡住了

异步: 任务提交之后,不原地等待任务的返回结果,直接去做其他事情
  	我提交的任务结果如何获取?
    任务的返回结果会有一个异步回调机制自动处理
1.8、阻塞非阻塞
描述的程序的运行状态
阻塞: 阻塞态
非阻塞: 就绪态、运行态

理想状态: 我们应该让我们的写的代码永远处于就绪态和运行态之间切换

总结: 最高效的一种组合就是异步非阻塞

2、进程 2.1、multiprocessing模块
python中的多线程无法利用CPU资源,在python中大部分情况使用多进程。python中提供了非常好的多进程包multiprocessing

multiprocessing模块用来开启子进程,并在子进程中执行功能(函数),该模块与多线程模块threading的编程接口类似

multiprocessing的功能众多:支持子进程、通信和共享数据、执行不同形式的同步,提供了Process、Queue、Pipe、Lock等组件
2.2、Process类 2.2.1、创建进程的类
Process([group [, target [, name [, args [, kwargs]]]]]),由该类实例化得到的对象,表示一个子进程中的任务(尚未启动)

强调:
1. 需要使用关键字的方式来指定参数
2. args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号
2.2.2、参数
group参数未使用,值始终为None

target表示调用对象,即子进程要执行的任务

args表示调用对象的位置参数元组,args=(1,2,'allen',)

kwargs表示调用对象的字典,kwargs={'name':'allen','age':18}

name表示子进程的名称
2.2.3、方法
p.start(): 启动进程,并调用该子进程中的p.run()
    
p.run(): 进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法

p.terminate(): 强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁
    
p.is_alive(): 如果p仍然运行,返回True

p.join([timeout]): 主线程等待p终止(强调: 是主线程处于等的状态,而p是处于运行的状态)。timeout是可选的超时时间,需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程
2.2.4、属性
p.daemon: 默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置

p.name: 进程的名称

p.pid: 进程的pid

p.exitcode: 进程在运行时为None、如果为–N,表示被信号N结束

p.authkey: 进程的身份验证键,默认是由os.urandom()随机生成的32字符的字符串。这个键的用途是为涉及网络连接的底层进程间通信提供安全性,这类连接只有在具有相同的身份验证键时才能成功
2.3、Process类的使用
一定要把开进程的代码写在if __name__=='__main__'下面

开一个进程和主进程是并发的关系,我start一下就是先告诉操作系统我要开一个进程
,然而它不会等待,它会直接去执行下面的代码,然后就开始执行子进程

strat(): 方法的功能

1.开启进程
2.执行功能
2.4、开启进程的两种方式 2.4.1、方式一
from multiprocessing import Process
import time

def task(n, name):
    print('{} is running'.format(name))
    time.sleep(n)
    print('{} is done'.format(name))

if __name__ == '__main__':
    obj1 = Process(target=task, args=(3, '进程1'))
    obj2 = Process(target=task, args=(5, '进程2'))
    obj1.start()
    obj2.start()
    obj1.join()  # 等待子进程obj1执行完成
    obj2.join()  # 等待子进程obj2执行完成
    print('主')
2.4.2、方式二
from multiprocessing import Process
import time

class Mytask(Process):
    def __init__(self, n, name):
        super().__init__()
        self.n = n
        self.name = name

    def run(self) -> None:
        print('{} is running'.format(self.name))
        time.sleep(self.n)
        print('{} is done'.format(self.name))

if __name__ == '__main__':
    obj1 = Mytask(3, '进程1')
    obj2 = Mytask(5, '进程2')
    obj1.start()
    obj2.start()
    obj1.join()
    obj2.join()
    print('主')
2.5、进程间数据相互隔离
from multiprocessing import Process
import time

number = 10

def task(n):
    global number  # 局部修改全局
    number = 20
    time.sleep(n)
    print('子进程中number的值为: {}'.format(number))  # 20

if __name__ == '__main__':
    t = Process(target=task, kwargs={'n': 1})
    t.start()
    t.join()  # 等待t子进程执行完成
    print('主进程中number的值为: {}'.format(number))  # 数据没有变,主进程中打印age和子进程的age没有关系,数据是隔离的,结果还是10
2.6、进程调度
1、先来先服务
2、短作业优先
3、时间片轮转
4、多级反馈队列
2.7、僵尸进程和孤儿进程
1、僵尸进程: 进程结束了,资源还没来得及回收
2、孤儿进程: 主进程挂了,子进程还没结束,它就会被专门的进程接管
2.8、进程对象及其他方法
from multiprocessing import Process, current_process
import os
import time

def task():
    print('子进程')
    print('task函数内子进程id: {}'.format(os.getpid()))
    print('task函数内子进程id: {}'.format(current_process().pid))
    print('task函数内子进程的父进程id: {}'.format(os.getppid()))
    print('task函数内: {}'.format(current_process().is_alive()))
    time.sleep(2)
    print('子进程结束')

if __name__ == '__main__':
    t = Process(target=task)
    t.start()
    t.join()
    t.terminate()
    time.sleep(0.1)
    print(t.is_alive())
    print('子进程id: {}'.format(t.pid))
    print('主进程id: {}'.format(os.getpid()))

总结:
1、windows:tasklist |findstr 进程id号
2、mac,Linux:ps aux | grep 进程id号
3、进程对象: t=Process(target=task)或者是在进程内部: current_process()
4、t.pid或者current_process().pid  # 获取进程id号
5、os.getpid()  # 同上,获取进程id号
6、os.getppid()  # 获取父进程id号,子进程中获取父进程id,等于父进程的id号
7、t.is_alive()或者current_process().is_alive()  # 查看进程是否存活
8、t.terminate()  # 关闭进程,在主进程关闭
2.9、守护进程
守护进程: 主进程一旦结束,子进程也结束

from multiprocessing import Process
import time

def task():
    print('子进程开始')
    time.sleep(2)
    print('子进程结束')

if __name__ == '__main__':
    t = Process(target=task)
    t.daemon = True  # 一定要加在启动之前
    t.start()
    print('主进程结束')

问题1: 主进程的父进程是谁?
      如果是用pycharm运行的代码主进程的父进程就是pycharm
问题2: 主进程开了很多子进程,每个都需要设置守护吗?
      主要还是看你的需求,你想让某个进程是守护,就设置t.daemon=True
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/833965.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号