程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2023-05(1)

二十四、Python之multiprocessing模块及进程池

发布于2020-02-26 11:25     阅读(604)     评论(0)     点赞(18)     收藏(5)


进程创建方法

      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

  1. import multiprocessing as mp
  2. from time import sleep
  3. def fun():
  4. print("子进程开始")
  5. sleep(3)
  6. print("子进程结束")
  7. if __name__ == '__main__':
  8. # 创建进程对象
  9. p = mp.Process(target=fun)
  10. # 启动进程
  11. p.start()
  12. # 回收进程
  13. p.join()

     示例2

  1. from multiprocessing import Process
  2. import os
  3. from time import sleep
  4. def fun1():
  5. sleep(4)
  6. print("吃饭", os.getpid(), os.getppid())
  7. def fun2():
  8. sleep(2)
  9. print("睡觉", os.getpid(), os.getppid())
  10. def fun3():
  11. sleep(5)
  12. print("打豆豆", os.getpid(), os.getppid())
  13. if __name__ == '__main__':
  14. fun_list = [fun1, fun2, fun3]
  15. jobs = []
  16. for f in fun_list:
  17. p = Process(target=f)
  18. jobs.append(p)
  19. p.start()
  20. for i in jobs:
  21. i.join()
  22. # 总耗时5s

示例3

  1. from multiprocessing import Process
  2. from time import sleep
  3. # 带参数的进程函数
  4. def worker(sec, name):
  5. for i in range(3):
  6. sleep(sec)
  7. print("I'm %s" % name)
  8. print("I'm working...")
  9. if __name__ == '__main__':
  10. # p = Process(target=worker, args=(2, "Baron"))
  11. p = Process(target=worker, kwargs={"name": "Abby", "sec": 2})
  12. p.start()
  13. p.join()

 

    3. 进程对象属性

p.name 进程名称

p.pid 对应子进程的PID号

p.is_alive() 查看子进程是否在生命周期

p.daemon 设置父子进程的退出关系

    如果设置为True则子进程会随父进程的退出而结束

    要求必须在start()前设置

    如果daemon设置成True 通常就不会使用 join()  

  1. from multiprocessing import Process
  2. from time import sleep, ctime
  3. def tm():
  4. for i in range(3):
  5. sleep(2)
  6. print(ctime())
  7. if __name__ == '__main__':
  8. p = Process(target=tm)
  9. print("Name:", p.name) # Process-1
  10. print("PID:", p.pid) # None start()后会生成
  11. print("is_alive:", p.is_alive()) # False start()后为 True
  12. print("daemon:", p.daemon) # False 默认值是False

自定义进程类

     1. 创建步骤

        【1】 继承Process

        【2】 重写 __init__ 方法添加自己的属性,使用super()加载父类属性

        【3】 重写run()方法

    2. 使用方法

        【1】 实例化对象

        【2】 调用start自动执行run方法

        【3】 调用join回收线程

  1. """
  2. 自定义进程类
  3. """
  4. from multiprocessing import Process
  5. # 自定义类
  6. class MyProcess(Process):
  7. def __init__(self, value):
  8. self.value = value
  9. super().__init__() # 加载父类init
  10. def f1(self):
  11. print("步骤1")
  12. def f2(self):
  13. print("步骤2")
  14. def run(self):
  15. self.f1()
  16. self.f2()
  17. p = MyProcess(2)
  18. p.start() # 执行run,作为一个子进程执行
  19. 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()

功能: 回收进程池中进程

  1. """
  2. 进程池
  3. """
  4. from multiprocessing import Pool
  5. from time import sleep
  6. def worker(msg):
  7. sleep(2)
  8. print(msg)
  9. if __name__ == '__main__':
  10. # 创建进程池
  11. pool = Pool(3)
  12. for i in range(18):
  13. msg = "Hello %d" % i
  14. pool.apply_async(worker, (msg,))
  15. # 结果会每2秒 执行完3个进程
  16. pool.close()
  17. pool.join()

 

发布了30 篇原创文章 · 获赞 3 · 访问量 1万+


所属网站分类: 技术文章 > 博客

作者:嘴巴嘟嘟

链接:https://www.pythonheidong.com/blog/article/233967/562ea53b9a97b5a7941e/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

18 0
收藏该文
已收藏

评论内容:(最多支持255个字符)