Python3 多进程编程(Multiprocess programming)

为什么使用多进程

  python中的多线程其实并不是真正的多线程,不能充分地使用多核CPU的资源,此时需要使用需要使用多进程解决问题。

具体用法

  Python中的多进程是通过multiprocessing模块来实现的,和多线程的threading.Thread类似,利用multiprocessing.Process来创建一个进程对象。进程对象的方法和线程对象的方法类似,也有start(), join()等。

  • 直接启用

    代码实例
    1. import multiprocessing
    2. from time import sleep
    3. def clock(interval):
    4. i = 0
    5. while i<5:
    6. i += 1
    7. print(f"Run >>> {i}")
    8. sleep(interval)
    9. print("Ending!")
    10. if __name__ == '__main__':
    11. p = multiprocessing.Process(target = clock, args = (1,))
    12. p.start()
    13. p.join()
    运行结果
    1. Run >>> 1
    2. Run >>> 2
    3. Run >>> 3
    4. Run >>> 4
    5. Run >>> 5
    6. Ending!
  • 继承自multiprocessing.Process调用

    与多线程使用方法类似

    • 直接继承Process
    • 重写run函数
    • 类实例可以直接运行
    代码实例
    1. import multiprocessing
    2. from time import sleep
    3. class ClockProcess(multiprocessing.Process):
    4. def __init__(self, interval):
    5. super().__init__()
    6. self.interval = interval
    7. def run(self):
    8. i = 0
    9. while i<5:
    10. i += 1
    11. print(f"Run >>> {i}")
    12. sleep(self.interval)
    13. print("Ending!")
    14. if __name__ == '__main__':
    15. p = ClockProcess(1)
    16. p.start()
    17. p.join()
    运行结果
    1. Run >>> 1
    2. Run >>> 2
    3. Run >>> 3
    4. Run >>> 4
    5. Run >>> 5
    6. Ending!
  • 守护进程

    • 设置该进程为守护进程,即认为此进程不重要,主进程结束后,该进程随即结束。
    • 用法Process.daemon = Ture
    未使用守护进程
    1. import multiprocessing
    2. from time import sleep
    3. def clock(interval):
    4. i = 0
    5. while i<5:
    6. i += 1
    7. print(f"Run >>> {i}")
    8. sleep(interval)
    9. print("Ending!")
    10. def run():
    11. p = multiprocessing.Process(target = clock, args = (1,))
    12. p.start()
    13. if __name__ == '__main__':
    14. run()
    15. sleep(2)
    16. print("ENDING!")
    运行结果
    1. Run >>> 1
    2. Run >>> 2
    3. ENDING!
    4. Run >>> 3
    5. Run >>> 4
    6. Run >>> 5
    7. Ending!
    使用守护进程
    1. import multiprocessing
    2. from time import sleep
    3. def clock(interval):
    4. i = 0
    5. while i<5:
    6. i += 1
    7. print(f"Run >>> {i}")
    8. sleep(interval)
    9. print("Ending!")
    10. def run():
    11. p = multiprocessing.Process(target = clock, args = (1,))
    12. p.daemon = True
    13. p.start()
    14. if __name__ == '__main__':
    15. run()
    16. sleep(2)
    17. print("ENDING!")
    运行结果
    1. Run >>> 1
    2. Run >>> 2
    3. ENDING!

Python多线程的通信

  进程是系统独立调度核分配系统资源的基本单位,进程之间是相互独立的,进程之间的数据也不能共享,这是多进程在使用中与多线程最明显的区别。

  所以要使用多进程来弥补Python中多线程的不足,解决多进程之间的通信时关键。

进程对列Queue

  在python多进程中,Queue其实就是进程之间的数据管道,实现进程通信。

生产者消费者问题

  • 仓库(固定大小的中间缓冲区)

  • 生产者

    持续生产数据传入仓库

  • 消费者

    持续从仓库总提取数据

  在实际运行时会产设的问题。生产者的主要作用是生成一定量的数据放到仓库中,然后重复此过程。

  与此同时,消费者也在仓库消耗这些数据。该问题的关键就是要保证生产者不会在仓库满时加入数据,消费者也不会在仓库空时消耗数据。

JoinableQueue

  • JoinableQueue同样通过multiprocessing使用。

  • JoinableQueue([maxsize]):就是一个Queue对象,但允许项目的使用者通知生成者项目已经被成功处理。

  • maxsize是队列中允许最大项数,省略则无大小限制。

  • 方法介绍:

    JoinableQueue与Queue对象的方法一致,且之外还具有:

    • JoinableQueue.task_done():使用者使用此方法发出信号,表示q.get()的返回项目已经被处理。如果调用此方法的次数大于从队列中删除项目的数量,将引发ValueError异常。
    • JoinableQueue.join():生产者调用此方法进行阻塞,直到队列中所有的项目均被处理。阻塞将持续到队列中的每个项目均调用JoinableQueue.task_done()方法为止。

Queue实例

  • 使用JoinableQueue实现生产者消费者模型

    代码

    1. import multiprocessing
    2. from time import ctime,sleep
    3. def consumer(input_q):
    4. print("消费开始:", ctime())
    5. while True:
    6. # 处理项
    7. item = input_q.get()
    8. print ("消费 >>>>>>>>>", item) # 此处替换为有用的工作
    9. input_q.task_done() # 发出信号通知任务完成
    10. sleep(1)
    11. print ("消费结束:", ctime()) ##此句未执行,因为q.join()收集到四个task_done()信号后,主进程启动,未等到print此句完成,程序就结束了
    12. def producer(sequence, output_q):
    13. print ("生产开始:", ctime())
    14. for item in sequence:
    15. output_q.put(item)
    16. print ("生产 >>>>>>>>>", item)
    17. sleep(1)
    18. print ("生产结束:", ctime())
    19. if __name__ == '__main__':
    20. q = multiprocessing.JoinableQueue()
    21. # 运行消费者进程
    22. cons_p = multiprocessing.Process (target = consumer, args = (q,))
    23. cons_p.daemon = True
    24. cons_p.start()
    25. # 生产多个项,sequence代表要发送给消费者的项序列
    26. # 在实践中,这可能是生成器的输出或通过一些其他方式生产出来
    27. sequence = [1,2,3,4]
    28. producer(sequence, q)
    29. # 等待所有项被处理
    30. q.join()
    运行结果
    1. 生产开始: Wed Oct 16 22:06:11 2019
    2. 生产 >>>>>>>>> 1
    3. 消费开始: Wed Oct 16 22:06:11 2019
    4. 消费 >>>>>>>>> 1
    5. 生产 >>>>>>>>> 2
    6. 消费 >>>>>>>>> 2
    7. 生产 >>>>>>>>> 3
    8. 消费 >>>>>>>>> 3
    9. 生产 >>>>>>>>> 4
    10. 消费 >>>>>>>>> 4
    11. 生产结束: Wed Oct 16 22:06:15 2019

管道Pipe

待续

Python3 多进程编程 - 学习笔记的更多相关文章

  1. Python3 多线程编程 - 学习笔记

    线程 什么是线程 特点 线程与进程的关系 Python3中的多线程 全局解释器锁(GIL) GIL是啥? GIL对Python程序有啥影响? 改善GIL产生的问题 Python3关于多线程的模块 多线 ...

  2. python多进程编程学习笔记

    摘自[https://www.cnblogs.com/chenhuabin/p/10070996.html] by 奥辰 赞

  3. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  4. Linux Shell编程学习笔记——目录(附笔记资源下载)

    LinuxShell编程学习笔记目录附笔记资源下载 目录(?)[-] 写在前面 第一部分 Shell基础编程 第二部分 Linux Shell高级编程技巧 资源下载 写在前面 最近花了些时间学习She ...

  5. DirectX 11游戏编程学习笔记之8: 第6章Drawing in Direct3D(在Direct3D中绘制)(习题解答)

            本文由哈利_蜘蛛侠原创,转载请注明出处.有问题欢迎联系2024958085@qq.com         注:我给的电子版是700多页,而实体书是800多页,所以我在提到相关概念的时候 ...

  6. 多线程编程学习笔记——async和await(一)

    接上文 多线程编程学习笔记——任务并行库(一) 接上文 多线程编程学习笔记——任务并行库(二) 接上文 多线程编程学习笔记——任务并行库(三) 接上文 多线程编程学习笔记——任务并行库(四) 通过前面 ...

  7. 多线程编程学习笔记——async和await(二)

    接上文 多线程编程学习笔记——async和await(一) 三.   对连续的异步任务使用await操作符 本示例学习如何阅读有多个await方法方法时,程序的实际流程是怎么样的,理解await的异步 ...

  8. 多线程编程学习笔记——async和await(三)

    接上文 多线程编程学习笔记——async和await(一) 接上文 多线程编程学习笔记——async和await(二) 五.   处理异步操作中的异常 本示例学习如何在异步函数中处理异常,学习如何对多 ...

  9. 多线程编程学习笔记——使用异步IO(一)

    接上文 多线程编程学习笔记——使用并发集合(一) 接上文 多线程编程学习笔记——使用并发集合(二) 接上文 多线程编程学习笔记——使用并发集合(三) 假设以下场景,如果在客户端运行程序,最的事情之一是 ...

随机推荐

  1. 超好用的thinkphp5.0/thinkphp5.1分页插件!详细使用步骤(内附代码)

    效果 tp5.0使用方法 page下载地址:进入下载页面 提取码:s75k 1,把page文件夹整个目录复制到 目录extend下 2,修改默认配置 app/config.php 把里面的 'pagi ...

  2. windows API 创建系统托盘图标

    系统托盘在我们使用的程序中很普遍,下面我们来看一个很不错的例子,使用Win32 API实现,对理解系统托盘有些帮助. [cpp] view plaincopy #include <windows ...

  3. postgresql修改自增序列

    ----删除前先解除 id 对该序列的依赖ALTER TABLE tablename ALTER COLUMN id SET DEFAULT null;DROP SEQUENCE IF EXISTS ...

  4. 使用VS2015制作安装包( 含相关的下载链接)

    补充: 在看下面的教程过程中,如果在下面的步聚1中没有 " Visual Studio Installer", 则需要通过下面的链接进行安装 Visual Studio Insta ...

  5. 2、Locust压力测试 实战

    创建测试脚本 创建Test()类继承TaskSet类 创建beigong() 方法表示一个行为,访问北弓官网首页.用@task() 装饰该方法为一个任务.1表示一个Locust实例被挑选执行的权重,数 ...

  6. 前端(十三)—— JavaScript高级:回调函数、闭包、循环绑定、面向对象、定时器

    回调函数.闭包.循环绑定.面向对象.定时器 一.函数高级 1.函数回调 // 回调函数 function callback(data) {} // 逻辑函数 function func(callbac ...

  7. 从零起步 系统入门Python爬虫工程师✍✍✍

    从零起步 系统入门Python爬虫工程师 爬虫(又被称为网页蜘蛛,网络机器人)就是模拟客户端发送网络请求,接收请求响应,一种按照一定的规则,自动地抓取互联网信息的程序. 原则上,只要是浏览器(客户端) ...

  8. pytest_按标记执行

    import pytest@pytest.mark.webtestdef test_send_http(): pass @pytest.mark.apptestdef test_devide(): p ...

  9. uptime - 告知系统运行了多久时间

    SYNOPSIS(总览) uptime uptime [-V] DESCRIPTION(描述) uptime 给出下列信息的一行显示. 当前时间, 系统运行了多久时间, 当前登陆的用户有多少, 以及前 ...

  10. 文件 IO

    io分类 在文件IO 中是通过文件描述符操作文件的,实际上是一个非负整数 头文件   #include <sys/types.h>   #include <sys/stat.h> ...