以前写点小程序其实根本不在乎并行,单核跑跑也没什么问题,而且我的电脑也只有双核四个超线程(下面就统称核好了),觉得去折腾并行没啥意义(除非在做IO密集型任务)。然后自从用上了32核128GB内存,看到 htop 里面一堆空载的核,很自然地就会想这个并行必须去折腾一下。后面发现,其实 Python 的并行真的非常简单。

multiprocessing vs threading

Python 自带的库又全又好用,这是我特别喜欢 Python 的原因之一。Python 里面有 multiprocessing 和 threading 这两个用来实现并行的库。用线程应该是很自然的想法,毕竟(直觉上)开销小,还有共享内存的福利,而且在其他语言里面线程用的确实是非常频繁。然而,我可以很负责任的说,如果你用的是 CPython 实现,那么用了 threading 就等同于和并行计算说再见了(实际上,甚至会比单线程更慢),除非这是个IO密集型的任务。

GIL

CPython 指的是 python.org 提供的 Python 实现。是的,Python 是一门语言,它有各种不同的实现,比如 PyPy, Jython, IronPython 等等……我们用的最多的就是 CPython,它几乎就和 Python 画上了等号。

CPython 的实现中,使用了 GIL 即全局锁,来简化解释器的实现,使得解释器每次只执行一个线程中的字节码。也就是说,除非是在等待IO操作,否则 CPython 的多线程就是彻底的谎言!

有关 GIL 下面两个资料写的挺好的:

multiprocessing.Pool

因为 GIL 的缘故 threading 不能用,那么我们就好好研究研究 multiprocessing。(当然,如果你说你不用 CPython,没有 GIL 的问题,那也是极佳的。)

首先介绍一个简单粗暴,非常实用的工具,就是 multiprocessing.Pool。如果你的任务能用 ys = map(f, xs) 来解决,大家可能都知道,这样的形式天生就是最容易并行的,那么在 Python 里面并行计算这个任务真是再简单不过了。举个例子,把每个数都平方:

import multiprocessing

def f(x):

return x * x

cores = multiprocessing.cpu_count()

pool = multiprocessing.Pool(processes=cores)

xs = range(5)

# method 1: map

print pool.map(f, xs) # prints [0, 1, 4, 9, 16]

# method 2: imap

for y in pool.imap(f, xs):

print y # 0, 1, 4, 9, 16, respectively

# method 3: imap_unordered

for y in pool.imap_unordered(f, xs):

print(y) # may be in any order

map 直接返回列表,而 i 开头的两个函数返回的是迭代器;imap_unordered 返回的是无序的。

当计算时间比较长的时候,我们可能想要加上一个进度条,这个时候 i 系列的好处就体现出来了。另外,有一个小技巧,就是输出 \r 可以使得光标回到行首而不换行,这样就可以制作简易的进度条了。

cnt = 0

for _ in pool.imap_unordered(f, xs):

sys.stdout.write('done%d/%d\r' % (cnt, len(xs)))

cnt += 1

更复杂的操作

要进行更复杂的操作,可以直接使用 multiprocessing.Process 对象。要在进程间通信可以使用:

其中我强烈推荐的就是 Queue,因为其实很多场景就是生产者消费者模型,这个时候用 Queue 就解决问题了。用的方法也很简单,现在父进程创建 Queue,然后把它当做 args 或者 kwargs 传给 Process 就好了。

使用 Theano 或者 Tensorflow 等工具时的注意事项

需要注意的是,在 import theano 或者 import tensorflow 等调用了 Cuda 的工具的时候会产生一些副作用,这些副作用会原样拷贝到子进程中,然后就发生错误,如:

could not retrieve CUDA device count: CUDA_ERROR_NOT_INITIALIZED

解决的方法是,保证父进程不引入这些工具,而是在子进程创建好了以后,让子进程各自引入。

如果使用 Process,那就在 target 函数里面 import。举个例子:

import multiprocessing

def hello(taskq, resultq):

import tensorflow as tf

config = tf.ConfigProto()

config.gpu_options.allow_growth=True

sess = tf.Session(config=config)

while True:

name = taskq.get()

res = sess.run(tf.constant('hello ' + name))

resultq.put(res)

if __name__ == '__main__':

taskq = multiprocessing.Queue()

resultq = multiprocessing.Queue()

p = multiprocessing.Process(target=hello, args=(taskq, resultq))

p.start()

taskq.put('world')

taskq.put('abcdabcd987')

taskq.close()

print(resultq.get())

print(resultq.get())

p.terminate()

p.join()

如果使用 Pool,那么可以编写一个函数,在这个函数里面 import,并且把这个函数作为 initializer 传入到 Pool 的构造函数里面。举个例子:

import multiprocessing

def init():

global tf

global sess

import tensorflow as tf

config = tf.ConfigProto()

config.gpu_options.allow_growth=True

sess = tf.Session(config=config)

def hello(name):

return sess.run(tf.constant('hello ' + name))

if __name__ == '__main__':

pool = multiprocessing.Pool(processes=2, initializer=init)

xs = ['world', 'abcdabcd987', 'Lequn Chen']

print pool.map(hello, xs)​

首发于博客 Python 多核并行计算

python多核并行计算_Python 多核并行计算相关推荐

  1. python多核并行计算_python多核并行

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! python中的并行由于cpython中的gil的存在我们可以暂时不奢望能在cp ...

  2. python做并行计算_python做并行计算可以吗

    python可以做并行计算,下面是相关介绍: 一.概览 Parallel Python是一个python模块,提供在SMP(具有多个处理器或多核的系统)和集群(通过网络连接的计算机)上并行执行pyth ...

  3. python3 多线程_图解|为什么 Python 多线程无法利用多核

    (给Python开发者加星标,提升Python技能) 来源:后端技术指南针 1.全局解释锁 如题: Python的多线程为什么不能利用多核处理器? 全局解释器锁(Global Interpreter ...

  4. python多线程不能利用多核cpu,但有时候多线程确实比单线程快。

    python 为什么不能利用多核 CPU  GIL 其实是因为在 python中有一个 GIL( Global Interpreter Lock),中文为:全局解释器锁.  1.最开始时候设计GIL是 ...

  5. python性能解决_Python性能优化的20条建议

    优化算法时间复杂度 算法的时间复杂度对程序的执行效率影响最大,在Python中可以通过选择合适的数据结构来优化时间复杂度,如list和set查找某一个元素的时间复杂度分别是O(n)和O(1).不同的场 ...

  6. python gpu编程_Python笔记_第四篇_高阶编程_进程、线程、协程_5.GPU加速

    Numba:高性能计算的高生产率 在这篇文章中,笔者将向你介绍一个来自Anaconda的Python编译器Numba,它可以在CUDA-capable GPU或多核cpu上编译Python代码.Pyt ...

  7. python gil 解除_python GIL的解读

    前言 本篇文章主要是看完UnderstandingGIL.pdf后的一些理解 http://www.dabeaz.com/python/UnderstandingGIL.pdf GIL什么是? 简单翻 ...

  8. python 线程退出_python线程退出

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 如果某线程并未使用很多 io 操作, 它会在自己的时间片内一直占用处理器(和 g ...

  9. python多线程库_python多线程库

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! python 多线程 多线程类似于同时执行多个不同程序,多线程运行有如下优点:使 ...

最新文章

  1. 基础的互联网连接词汇—Vecloud微云
  2. python操作界面_Python使用PyQt5的Designer工具创建UI界面
  3. 原码一位乘法器设计_数字IC校招基础知识点复习(七)——超前进位加法器、Wallace树、Booth乘法器...
  4. 研究生就业竞争力弱化 “皇帝女儿也愁嫁”
  5. CNN卷积神经网络-tensorflow
  6. 面试常被问的65个问题及回答技巧(请收藏)
  7. java delphi aes加密算法_AES加密算法(Delphi源码)
  8. Mac下Appium环境搭建
  9. 小卡,功能强大– M.2格式的工业通讯
  10. DC Administration Services 宣布ISDA裁决委员会2021年申请流程
  11. python量化选股策略 源码_【一点资讯】Python实现行业轮动量化选股【附完整源码】...
  12. 第5组UI 让你的界面酷炫到底-ViewAniMator之ViewSwitcher、ImageSwitcher(图像切换器)、TextSwitcher(文本切换器)、ViewFlipper
  13. 百度地图实现自定义搜索
  14. 用Python中的hashlib实现md5和sha加密
  15. Rabbitmq客户端接收消息为字符数组解决
  16. STM32F103驱动HCSR04超声波测距显示
  17. markdown多级列表
  18. 安徽马鞍山郑蒲港地图编码
  19. Definition, Lemma ,Theorem ,Proposition ,Corollary ,Proof ,Conjecture ,Axiom 概念的含义和区别
  20. ransac直线段拟合

热门文章

  1. shiro从入门到精通
  2. 网络攻防技术——幽灵攻击实验
  3. 3.2.3 抽象工厂模式(Abstract Factory) -《SSM深入解析与项目实战》
  4. bat,copy 文件
  5. 华为android11新特性,华为EMUI11曝光,有新特性,看看你的手机支不支持
  6. 关于 本地仓库有jar包,但idea找不到的问题
  7. 解决idea中@WebServlet无效问题
  8. 你说你还不会Redis?别怕,今天带你搞定它!
  9. 图解机器学习-空间概念-随机梯度算法matlab解释
  10. win10常用快捷键、命令和脚本