前言

本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。

作者:东哥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基础知识点:多进程的应用讲解的更多相关文章

  1. 最全Python基础知识点梳理

    本文主要介绍一些平时经常会用到的python基础知识点,用于加深印象,也算是对于学习这门语言的一个总结与回顾.python的详细语法介绍可以查看官方编程手册,也有一些在线网站可以学习 python语言 ...

  2. Python基础知识点小结

    1.Python基础知识 在Python中的两种注释方法,分别是#注释和引号('''   ''')注释,#注释类似于C语言中的//注释,引号注释类似于C语言中的/*   */注释.接着在Python中 ...

  3. Python基础知识点总结

    Python基础知识与常用数据类型 一.Python概述: 1.1.Python的特点: 1.Python是一门面向对象的语言,在Python中一切皆对象 2.Python是一门解释性语言 3.Pyt ...

  4. python基础知识点四

    网络编程(socket) 软件开发的架构: 两个程序之间通讯的应用大致通过从用户层面可以分为两种: 1是C/S,即客户端与服务端,为应用类的,比如微信,网盘等需要安装桌面应用的 2是B/S,即浏览器与 ...

  5. python基础知识点三

    内置函数和匿名函数 python 一共有68个内置的函数:它们就是python提供给你直接可以拿来使用的所有函数 内置函数的图:链接 :https://www.processon.com/mindma ...

  6. python 基础知识点整理 和详细应用

    Python教程 Python是一种简单易学,功能强大的编程语言.它包含了高效的高级数据结构和简单而有效的方法,面向对象编程.Python优雅的语法,动态类型,以及它天然的解释能力,使其成为理想的语言 ...

  7. Python基础知识点

    自学记录: 1.字符串 python中单引号和双引号使用完全相同. 使用三引号('''或""")可以指定一个多行字符串. 转义符 '\' 反斜杠可以用来转义,使用r可以让 ...

  8. python 基础知识点二

    深浅copy 1对于赋值运算来说,l1与l2指向的是同一个内存地址,所以他们是完全一样的. l1 = [1,2,3,['barry','alex']] l2 = l1 l1[0] = 111 prin ...

  9. python 基础知识点一

    基础数据类型初始. 数字:int 12,3,45 + - * / **    int: bit_lenth()转化为2进制的最小位数. % 取余数 ps:type() 字符串转化成数字:int(str ...

随机推荐

  1. window 开机重启运行bat文件(运行java的jar包)

    1:直接打开电脑的目录:(记得勾选查看隐藏项目) C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp,在里面新建start.bat ...

  2. SourceTree使用详解(连接远程仓库,克隆,拉取,提交,推送,新建/切换/合并分支,冲突解决)

    前言: 俗话说的好工欲善其事必先利其器,Git分布式版本控制系统是我们日常开发中不可或缺的.目前市面上比较流行的Git可视化管理工具有SourceTree.Github Desktop.Tortois ...

  3. GitHub 热点速览 Vol.25:距离优雅编程你差个它

    作者:HelloGitHub-小鱼干 摘要:如何优雅地夸一个程序员呢?vscode-rainbow-fart 作为一个彩虹屁的项目,深得程序员心,能在你编程时疯狂称赞你的除了你自己,还有它.除了鼓励之 ...

  4. Qt布局的简单介绍

    1  介绍 参考视频:https://www.bilibili.com/video/BV1XW411x7NU?p=25 布局的好处:布局之后,改变主窗口大小,其余窗口可以自适应. 2  布局分类 垂直 ...

  5. intellij配置github

    一.在IDEA中设置Git,在File-->Setting->Version Control-->Git-->Path to Git executable选择你的git安装后的 ...

  6. Perl入门(一)Perl的基本类型及运算符

    在学习Perl的基础之前,还是希望大家有空去看以下Perl的简介.百度百科 一.Perl的基本类型 Per的基本类型分为两种:数值型和字符串型. 数值型可细分为 整数型.如123. 浮点型.如123. ...

  7. Spring 面试详解

    SpringSpring就像是整个项目中装配bean的大工厂,在配置文件中可以指定使用特定的参数去调用实体类的构造方法来实例化对象.Spring的核心思想是IoC(控制反转),即不再需要程序员去显式地 ...

  8. CSS——文本超出隐藏显示省略号

    文本超出隐藏显示省略号 1.单行文本的溢出显示省略号 overflow: hidden; text-overflow:ellipsis; white-space: nowrap; // overflo ...

  9. vue全家桶(2.3)

    3.4.嵌套路由 实际生活中的应用界面,通常由多层嵌套的组件组合而成.同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件,例如: 再来看看下面这种更直观的嵌套图: 接下来我们需要实现下面这种 ...

  10. JavaScript基础Curry化(021)

    时候我们希望函数可以分步接受参数,并在所有参数都到位后得到执行结果.为了实现这种机制,我们先了解函数在Javascript中的应用过程: 1. 函数的“应用”(Function Application ...