multiprocessing 模块(含进程池,消息队列)

本文详细介绍了Python的multiprocessing模块,包括如何创建进程,自定义进程类,以及使用进程池。还讨论了进程间通信(IPC),特别是消息队列的使用,阐述了其在多进程中的重要性和实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

multiprocessing 模块创建进程

进程创建方法

  1. 流程特点
    【1】 将需要子进程执行的事件封装为函数
    【2】 通过模块的Process类创建进程对象,关联函数
    【3】 可以通过进程对象设置进程信息及属性
    【4】 通过进程对象调用start启动进程
    【5】 通过进程对象调用join回收进程
  2. 基本接口使用
    Process()
    功能 : 创建进程对象
    参数 : target 绑定要执行的目标函数
    args 元组,用于给target函数位置传参
    kwargs 字典,给target函数键值传参
    p.start()
    功能 : 启动进程
    注意:启动进程此时target绑定函数开始执行,该函数作为子进程执行内容,此时进程真正被创建
    p.join([timeout])
    功能:阻塞等待回收进程
    参数:超时时间
    注意:
    使用multiprocessing创建进程同样是子进程复制父进程空间代码段,父子进程运行互不
    影响。
    子进程只运行target绑定的函数部分,其余内容均是父进程执行内容。
    multiprocessing中父进程往往只用来创建子进程回收子进程,具体事件由子进程完成。
    multiprocessing创建的子进程中无法使用标准输入
  3. 进程对象属性

p.name 进程名称
p.pid 对应子进程的PID号
p.is_alive() 查看子进程是否在生命周期
p.daemon 设置父子进程的退出关系
如果设置为True则子进程会随父进程的退出而结束
要求必须在start()前设置
如果daemon设置成True 通常就不会使用 join()

自定义进程类

  1. 创建步骤
    【1】 继承Process类
    【2】 重写__init__方法添加自己的属性,使用super()加载父类属性
    【3】 重写run()方法
  2. 使用方法
    【1】 实例化对象
    【2】 调用start自动执行run方法
    【3】 调用join回收进程

进程池实现

  1. 必要性
    【1】 进程的创建和销毁过程消耗的资源较多
    【2】 当任务量众多,每个任务在很短时间内完成时,需要频繁的创建和销毁进程。此时对计算机压力较大
    【3】 进程池技术很好的解决了以上问题。
  2. 原理

创建一定数量的进程来处理事件,事件处理完进 程不退出而是继续处理其他事件,直到所有事件全都处理完毕统一销毁。增加进程的重复利用,降低资源消耗。

  1. 进程池实现

【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()
功能: 回收进程池中进程

进程间通信(IPC)

  1. 必要性: 进程间空间独立,资源不共享,此时在需要进程间数据传输时就需要特定的手段进行数据通信。

  2. 常用进程间通信方法

管道 消息队列 共享内存 信号 信号量 套接字

消息队列

1.通信原理

在内存中建立队列模型,进程通过队列将消息存入,或者从队列取出完成进程间通信。

  1. 实现方法
from multiprocessing import Queue

q = Queue(maxsize=0)
功能: 创建队列对象
参数:最多存放消息个数
返回值:队列对象

q.put(data,[block,timeout])
功能:向队列存入消息
参数:data  要存入的内容
block  设置是否阻塞 False为非阻塞
timeout  超时检测

q.get([block,timeout])
功能:从队列取出消息
参数:block  设置是否阻塞 False为非阻塞
timeout  超时检测
返回值: 返回获取到的内容

q.full()   判断队列是否为满
q.empty()  判断队列是否为空
q.qsize()  获取队列中消息个数
q.close()  关闭队列

下为消息队列演示

"""
queue_test.py
消息队列演示
"""
from multiprocessing import Queue,Process
from time import sleep
from random import randint

"""
父进程中创建IO,子进程从父进程中获取IO对象,实际上
他们操作的是同一个IO,属性相互影响
如果在各自进程中创建IO对象,那么这些IO对象互相没有
任何影响
"""


# 创建消息队列
q = Queue(3)

def handle():
    while True:
        try:
            # 获取消息
            x,y = q.get(timeout=8)
        except Exception as e:
            print(e)
            break
        else:
            print("%d+%d=%d"%(x,y,x+y))

def request():
    for i in range(6):
        sleep(randint(1,16))
        x = randint(1,100)
        y = randint(1,100)
        q.put((x,y)) #存入消息

p1 = Process(target=handle)
p2 = Process(target=request)
p1.start()
p2.start()
p1.join()
p2.join()

注:上图所示代码通过消息队列将线程p2产生的随机数传给线程p1,并输出它们的和

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值