进程创建方法
1. 流程特点
【1】 将需要子进程执行的事件封装为函数
【2】 通过模块的Process类创建进程对象,关联函数
【3】 可以通过进程对象设置进程信息及属性
【4】 通过进程对象调用start启动进程
【5】 通过进程对象调用join回收进程
2. 基本接口使用
Process()
功能 : 创建进程对象
参数 : target 绑定要执行的目标函数
args 元组,用于给target函数位置传参
kwargs 字典,给target函数键值传参
p.start()
功能:启动进程
注意:启动进程此时target绑定函数开始执行,该函数作为子进程执行内容,此时进程真正被创建
p.join([timeout])
功能:阻塞等待回收进程
参数:超时时间
注意
【1】使用multiprocessing创建进程同样是子进程复制父进程空间代码段,父子进程运行互不影响。
【2】子进程只运行target绑定的函数部分,其余内容均是父进程执行内容。
【3】multiprocessing中父进程往往只用来创建子进程回收子进程,具体事件由子进程完成。
【4】multiprocessing创建的子进程中无法使用标准输入
示例1
import multiprocessing as mp
from time import sleep
def fun():
print("子进程开始")
sleep(3)
print("子进程结束")
if __name__ == '__main__':
# 创建进程对象
p = mp.Process(target=fun)
# 启动进程
p.start()
# 回收进程
p.join()
示例2
from multiprocessing import Process
import os
from time import sleep
def fun1():
sleep(4)
print("吃饭", os.getpid(), os.getppid())
def fun2():
sleep(2)
print("睡觉", os.getpid(), os.getppid())
def fun3():
sleep(5)
print("打豆豆", os.getpid(), os.getppid())
if __name__ == '__main__':
fun_list = [fun1, fun2, fun3]
jobs = []
for f in fun_list:
p = Process(target=f)
jobs.append(p)
p.start()
for i in jobs:
i.join()
# 总耗时5s
示例3
from multiprocessing import Process
from time import sleep
# 带参数的进程函数
def worker(sec, name):
for i in range(3):
sleep(sec)
print("I'm %s" % name)
print("I'm working...")
if __name__ == '__main__':
# p = Process(target=worker, args=(2, "Baron"))
p = Process(target=worker, kwargs={"name": "Abby", "sec": 2})
p.start()
p.join()
3. 进程对象属性
p.name 进程名称
p.pid 对应子进程的PID号
p.is_alive() 查看子进程是否在生命周期
p.daemon 设置父子进程的退出关系
如果设置为True则子进程会随父进程的退出而结束
要求必须在start()前设置
如果daemon设置成True 通常就不会使用 join()
from multiprocessing import Process
from time import sleep, ctime
def tm():
for i in range(3):
sleep(2)
print(ctime())
if __name__ == '__main__':
p = Process(target=tm)
print("Name:", p.name) # Process-1
print("PID:", p.pid) # None start()后会生成
print("is_alive:", p.is_alive()) # False start()后为 True
print("daemon:", p.daemon) # False 默认值是False
自定义进程类
1. 创建步骤
【1】 继承Process类
【2】 重写 __init__ 方法添加自己的属性,使用super()加载父类属性
【3】 重写run()方法
2. 使用方法
【1】 实例化对象
【2】 调用start自动执行run方法
【3】 调用join回收线程
"""
自定义进程类
"""
from multiprocessing import Process
# 自定义类
class MyProcess(Process):
def __init__(self, value):
self.value = value
super().__init__() # 加载父类init
def f1(self):
print("步骤1")
def f2(self):
print("步骤2")
def run(self):
self.f1()
self.f2()
p = MyProcess(2)
p.start() # 执行run,作为一个子进程执行
p.join()
进程池实现
代码示例:day8/pool.py
1. 必要性
【1】 进程的创建和销毁过程消耗的资源较多
【2】 当任务量众多,每个任务在很短时间内完成时,需要频繁的创建和销毁进程。此时对计算机压力较大
【3】 进程池技术很好的解决了以上问题。
2. 原理
创建一定数量的进程来处理事件,事件处理完进程不退出而是继续处理其他事件,直到所有事件全都处理完毕统一销毁。增加进程的重复利用,降低资源消耗。
3. 进程池实现
【1】 创建进程池对象,放入适当的进程
from multiprocessing import Pool
Pool(processes)
功能: 创建进程池对象
参数: 指定进程数量,默认根据系统自动判定
【2】 将事件加入进程池队列执行
pool.apply_async(func,args,kwds)
功能: 使用进程池执行 func事件
参数: func 事件函数
args 元组 给func按位置传参
kwds 字典 给func按照键值传参
返回值: 返回函数事件对象
【3】 关闭进程池
pool.close()
功能: 关闭进程池
【4】 回收进程池中进程
pool.join()
功能: 回收进程池中进程
"""
进程池
"""
from multiprocessing import Pool
from time import sleep
def worker(msg):
sleep(2)
print(msg)
if __name__ == '__main__':
# 创建进程池
pool = Pool(3)
for i in range(18):
msg = "Hello %d" % i
pool.apply_async(worker, (msg,))
# 结果会每2秒 执行完3个进程
pool.close()
pool.join()