Python之multiprocessing模块及进程池

进程创建方法

      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()

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章