Python基础知识点:多进程的应用讲解
前言
本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。
作者:东哥IT笔记
现在很多CPU都支持多核,甚至是手机都已经开始支持多核了。而Python的GIL(Global Interpreter Locko)则使得其没法使用这些多核带来的优势。还好从Python2.6开始,引入了multiprocessing模块,我们终于可以使用多核带来的便利了。
本文,你会学习到下面这些内容:
- 使用多进程的优点
- 使用多进程的缺点
- 使用multiprocessing来创建多进程
- Process的子类化
- 创建进程池
本文并不是一个multiprocessing的全面的介绍,假如你想全面的了解它,可以参见官方的文档:
https://docs.python.org/2/library/multiprocessing.html
下面让我们开始吧!
使用多进程的优点
使用多进程有很多优点:
- 多进程使用独立的内存空间
- 相比于线程,代码更加直观
- 能够使用多个CPU/多核
- 避免GIL
- 子进程可以被kill(和thread不同)
- multiprocessing有和threading.Thread类似的接口
- 对CPU绑定的进程比较好(加密,二进制搜索,矩阵乘法等)
下面我们来看看使用多进程有什么缺点:
使用多进程的缺点
使用多进程也有一些缺点:
- 进程间通信更加复杂
- 内存的占用大于线程
使用multiprocessing来创建进程
multiprocessing是用来模拟threading.Thread类工作的。下面就是一个使用它的例子:
import multiprocessing
import random
import time def worker(name: str) -> None:
print(f'Started worker {name}')
worker_time = random.choice(range(1, 5))
time.sleep(worker_time)
print(f'{name} worker finished in {worker_time} seconds') if __name__ == '__main__':
processes = []
for i in range(5):
process = multiprocessing.Process(target=worker,
args=(f'computer_{i}',))
processes.append(process)
process.start() for proc in processes:
proc.join()
首先第一步需要import multiprocessing模块,另外两个import分别是为random和time服务的。
worker函数就是用来假装做一些事情,传入一个name的参数,没有什么返回,他首先打印name的值,然后随机sleep一段时间用来模拟做一段很长时间的工作,最后打印work finish。
紧接着,你使用multiprocessing.Process创建了5个进程,他的使用和threading.Tread()比较类似,你告诉Process哪个目标函数需要调用,以及会传入什么参数给他们,然后你调用了start函数来启动进程。另外你会把这些进程加入到一个list中。
最后,你遍历这个list,调用join方法,这个方法其实就是告诉Python等到进程结束。
假如你run这个函数,你会看到类似下面这样的输出:
其实你每次运行这个函数,结果都会有稍许的不同,主要还是因为你调用了random函数,你可以试试,看看你自己的输出。
Process的子类化
multiporcessing模块中的Process类是可以子类化的,他和threading.thread的类差不多。我们来看下面代码:
# worker_thread_subclass.py
import random
import multiprocessing
import time
class WorkerProcess(multiprocessing.Process):
def __init__(self, name):
multiprocessing.Process.__init__(self)
self.name = name
def run(self):
"""
Run the thread
"""
worker(self.name)
def worker(name: str) -> None:
print(f'Started worker {name}')
worker_time = random.choice(range(1, 5))
time.sleep(worker_time)
print(f'{name} worker finished in {worker_time} seconds')
if __name__ == '__main__':
processes = []
for i in range(5):
process = WorkerProcess(name=f'computer_{i}')
processes.append(process)
process.start()
for process in processes:
process.join()
这里,我们写了一个multiprocess.Process()的子类,并且重写了run()方法。
其他方面和上面的例子其实是类似的,现在我们可以来看看具体的输出,和上面的也类似。
创建一个进程池
假如你有很多进程需要运行,有时你希望能够限制进程运行的数目。比如说,你需要运行20个进程,但是你只有4个核,那么你可以使用multiprocessing模块来创建一个进程池,用它来限制每次进程运行的数目到4个。
下面是示例的代码:
import random
import time
from multiprocessing import Pool
def worker(name: str) -> None:
print(f'Started worker {name}')
worker_time = random.choice(range(1, 5))
time.sleep(worker_time)
print(f'{name} worker finished in {worker_time} seconds')
if __name__ == '__main__':
process_names = [f'computer_{i}' for i in range(15)]
pool = Pool(processes=5)
pool.map(worker, process_names)
pool.terminate()
这个例子中,worker函数还是一样的,主要是后面的代码, 我们创建了一个进程池,它的数目是5,也就意味着最大的运行数目是5。使用这个pool,你需要调用map()方法,然后把你需要的调用的方法和参数传递给他。
这样的话,Python每次只会使用5个进程来运行直到结束。最后你需要调用terminate()函数,否则你会发现下面的错误:
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/multiprocessing/resource_tracker.py:216:
UserWarning: resource_tracker: There appear to be 6 leaked semaphore objects to clean up at shutdown
这个代码的具体输出如下所示:
Python基础知识点:多进程的应用讲解的更多相关文章
- 最全Python基础知识点梳理
本文主要介绍一些平时经常会用到的python基础知识点,用于加深印象,也算是对于学习这门语言的一个总结与回顾.python的详细语法介绍可以查看官方编程手册,也有一些在线网站可以学习 python语言 ...
- Python基础知识点小结
1.Python基础知识 在Python中的两种注释方法,分别是#注释和引号(''' ''')注释,#注释类似于C语言中的//注释,引号注释类似于C语言中的/* */注释.接着在Python中 ...
- Python基础知识点总结
Python基础知识与常用数据类型 一.Python概述: 1.1.Python的特点: 1.Python是一门面向对象的语言,在Python中一切皆对象 2.Python是一门解释性语言 3.Pyt ...
- python基础知识点四
网络编程(socket) 软件开发的架构: 两个程序之间通讯的应用大致通过从用户层面可以分为两种: 1是C/S,即客户端与服务端,为应用类的,比如微信,网盘等需要安装桌面应用的 2是B/S,即浏览器与 ...
- python基础知识点三
内置函数和匿名函数 python 一共有68个内置的函数:它们就是python提供给你直接可以拿来使用的所有函数 内置函数的图:链接 :https://www.processon.com/mindma ...
- python 基础知识点整理 和详细应用
Python教程 Python是一种简单易学,功能强大的编程语言.它包含了高效的高级数据结构和简单而有效的方法,面向对象编程.Python优雅的语法,动态类型,以及它天然的解释能力,使其成为理想的语言 ...
- Python基础知识点
自学记录: 1.字符串 python中单引号和双引号使用完全相同. 使用三引号('''或""")可以指定一个多行字符串. 转义符 '\' 反斜杠可以用来转义,使用r可以让 ...
- python 基础知识点二
深浅copy 1对于赋值运算来说,l1与l2指向的是同一个内存地址,所以他们是完全一样的. l1 = [1,2,3,['barry','alex']] l2 = l1 l1[0] = 111 prin ...
- python 基础知识点一
基础数据类型初始. 数字:int 12,3,45 + - * / ** int: bit_lenth()转化为2进制的最小位数. % 取余数 ps:type() 字符串转化成数字:int(str ...
随机推荐
- 跟着whatwg看一遍事件循环
前言 对于单线程来说,事件循环可以说是重中之重了,它为任务分配不同的优先级,井然有序的调度.让js解析,用户交互,页面渲染等互不冲突,各司其职. 我们书写的代码无时无刻都在和事件循环打交道,要想写出更 ...
- springboot的jar为何能独立运行
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- Mariadb之事务隔离级别
上一篇我们聊到了mariadb的锁,以及怎么手动加锁和解锁等等,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13196905.html:今天我们来聊一聊mar ...
- express高效入门教程(2)
2.请求和响应 2.1.请求相关 2.1.1.返回一个html页面 // 注意path模块需要先引入 app.get('/', function (req, res){ res.sendFile(pa ...
- 【SpringCloud】Gateway 配置全局过滤器获取请求参数和响应值
[SpringCloud]Gateway 配置全局过滤器获取请求参数和响应值 实现Ordered接口getOrder()方法,数值越小越靠前执行,记得这一点就OK了. 获取请求参数RequestBod ...
- Redis为何是单线程的
以前一直有个误区,以为:高性能服务器 一定是 多线程来实现的 原因很简单因为误区二导致的: 多线程 一定比 单线程 效率高.其实不然. redis 核心就是 如果我的数据全都在内存里,我单线程的去操作 ...
- css3支持动画吗?css3可以用于网页动画的展现吗
CSS3 主要可以分为几个模块:边框和背景,渐变,文字特效,字体,2D/3D转换,动画(过渡动画和动画),选择器,盒模型,多列布局,用户界面. css3动画有2类:一种是transition的,另一种 ...
- 线程基础知识01-Thread类,Runnable接口
常见面试题:创建一个线程的常用方法有哪些?Thread创建线程和Runnable创建线程有什么区别? 答案通常集中在,继承类和实现接口的差别上面: 如果深入问一些问题:1.要执行的任务写在run()方 ...
- Redis哨兵集群创建脚本--v1
基础环境 操作系统版本 CentOS Linux release 7.6.1810 (Core) Docker 版本 19.03.11, build 42e35e61f3 Redis 版本 3 ...
- F5隐写工具使用
0x00 前言 今天在实验吧看到一个图片隐写的题目,用了stegslove和winHex分析一通发现并没有什么有效信息.看了评论区大佬的提示说用到了F5隐写工具,所以百度教程用了一下,发现确实解决 ...