本文是如何《优雅地实现Python通用多线程/进程并行模块》的后续。因为我发现,自认为懂了一点多线程开发的皮毛,写了那么个multi_helper的玩意儿,后来才发现我靠原来就是一坨屎。自己辛苦开发的并行库,在Python的原生类库中就有了优雅地多的实现。并且还有更优雅的asyncio库!这简直让人累觉不爱。

首先,并行和并发是不同的。100个进程可以在1个CPU上并发地执行,但却能在4个CPU上并行地执行。这就能看出两者的不同。

在实际编程中,有大量的计算或IO是一下子无法结束的。那么如何充分利用各种资源呢?有两个流派:

  • 多进程,多线程(并行)
  • 协程 (并发)

本文实在不能算完整,但汇集了笔者觉得很精髓的不少内容,因此可以认为是一篇综述性文章。

多线程和多进程

先说前者,定义本身是常识就不多说。初级程序员为了让程序变快,于是就狂开线程,不论是IO操作还是计算,能开100个就绝不开50个。线程回收一律不管,这程序只能是玩具。

不过,众所周知Python有GIL(全局解释器锁),任何时候都只有一个线程在工作。那多线程加速还玩个屁啊?!龟叔站出来了,他说:

  • Python在IO操作时,会自动释放GIL,因此IO密集型程序的多线程是有意义的
  • 即使不能多线程,还能多进程,这才是核武器。而Python有非常好用的multiprocessing库解决进程间协同问题。

然而,这些耗时任务,如果不需要知道结果,那还好说(很多程序员直接就把结果写到不同的文件里去,从而避免此问题,太low了)。可是每次都写文件再读出来这太麻烦了。如何收集计算结果呢?

笔者那个工具的做法,是将结果保存到一个队列中,从外部对其进行消费。但Python官方库早就有类似的实现了,多线程和多进程版本分别叫ThreadPoolExecutorProcessPoolExecutor。至于怎么用,出门问度娘。老司机在文章里贴代码太没有逼格了。

好,你度娘上完了。我们会发现他们都在concurrent.futures库里。这个表述很有意思。这是未来才能知道结果的任务,因此叫future。 在《Python高手之路》的第14章里,这样的概念叫期物。你如果你要获取某个任务的result,就必须等待该任务完成。也可以创建任务的数组,然后批量去执行它。类似的还有C#的async关键字以及task的result属性。

让我觉得比较神奇的是,Python的python-parallelize库,就能隐含地将for循环转换为并行for循环,代码更加简洁。这才是多进程的终极神器。写法如下:

import os
from parallelize import parallelizefor i in parallelize(range(100)):print(os.getpid(), i)

你要做的,仅仅是在迭代器外面套上套子,其他并行的操作就都由它执行完了。你猜这个库的核心代码有多少行?30行不到!它用os.fork创建出很多子进程,之后将不同的任务分配到这些进程上。而代码编写和串行程序几乎没有区别。

对多数人来说,高阶函数本来就比较反人类。这样写下来反而会清爽很多。值得学习!这部分写完了,我们进入协程的神秘世界。

asyncio 和 yield from

协程(coroutine)是比线程更轻量级的概念。大家会好奇协程的本质,因为当年学C语言时可是完全没这个东西啊。协程说白了就是语法糖。编译器会把协程的一坨东西整合到大的状态机里,类似于一堆switch-case和while的代码里,从而实现无缝调度。但对代码编写者来说,同一语义的依然能在同一个代码位置,从而更好理解。

yield是Python中的关键字。我们熟悉的是它的迭代生成器用法。更高阶的则是协程。例如:

a=yield b

如果你认为a=b,那就大错特错了。a是外部send函数的返回值。至于更详细的信息,可参考

http://www.jianshu.com/p/d09778f4e055

到了Python3, 更丧心病狂的yield from横空出世。最浅显的理解,是下面的代码:

def merge():yield from 'ABC'yield from '123'

于是在merge执行循环时,A,B,C,1,2,3会依次返回。那么肯定会有人纳闷,为何不直接itertools.chain呢?因为yield from有更复杂的功能,即能够让外部的generator对内部做消息传递。yield from 就像一个套子,无缝地将生成器merge了起来。

更详细的信息,可参考

http://blog.theerrorlog.com/yield-from-in-python-3.html

它有什么用呢?asyncio.

如果你喜欢C#的await和async关键字,则一定会对它的表现印象深刻。异步函数再也不用像js那样做疯狂的回调,顿时代码清晰了很多。这些也是编译器大人的功劳。

详细的可参考:

http://blog.jobbole.com/63897/

看得其实还是晕乎乎的,尽管我自认为对yield和协程有了相对充分的了解却依然如此。

结语

大神说,不要重复造轮子。你会发现之前想做的所有事情,都有远比你想的优雅的多的实现

不过问题在于,用了协程,yield from, asyncio,别人就看不懂我写的代码了,并且不得不升级到py3,可维护性顿时下降很多。因为我发现,就我身边会python的人来说,熟悉且能灵活使用以上那些语义的人不到百分之一。

有任何问题,随时交流。

转载于:https://www.cnblogs.com/buptzym/p/6950172.html

Python 多线程进程高级指南(二)相关推荐

  1. 多线程python_python高级之多线程

    python高级之多线程 本节内容 线程与进程定义及区别 python全局解释器锁 线程的定义及使用 互斥锁 线程死锁和递归锁 条件变量同步(Condition) 同步条件(Event) 信号量 队列 ...

  2. 获得进程id_浅谈python中的多线程和多进程(二)

    原创:hxj7 本文继续分享一个关于python多线程和多进程区别的例子 前文<浅谈python中的多线程和多进程>中我们分享过一个例子,就是分别利用python中的多线程和多进程来解决高 ...

  3. Python面试题大全(二):python高级语法

    目录 Python高级 元类 42.Python中类方法.类实例方法.静态方法有何区别? 43.遍历一个object的所有属性,并print每一个属性名? 44.写一个类,并让它尽可能多的支持操作符? ...

  4. ML之XGBoost:XGBoost参数调优的优秀外文翻译—《XGBoost中的参数调优完整指南(带python中的代码)》(二)

    ML之XGBoost:XGBoost参数调优的优秀外文翻译-<XGBoost中的参数调优完整指南(带python中的代码)>(二) 目录 2. xgboost参数/XGBoost Para ...

  5. python爬虫进程和线程的区别_熬了两个通宵写的!终于把多线程和多进程彻底讲明白了!...

    我们知道,在一台计算机中,我们可以同时打开许多软件,比如同时浏览网页.听音乐.打字等等,看似非常正常.但仔细想想,为什么计算机可以做到这么多软件同时运行呢?这就涉及到计算机中的两个重要概念:多进程和多 ...

  6. Python多线程多进程、异步、异常处理等高级用法

    文章目录 前言 多线程多进程 多线程 多进程 协程 总结 异步 基本概念 异步编程 asyncio aiohttp 异常 常见异常 异常处理 自定义异常 lambda表达式 lambda表达式用法 高 ...

  7. Android 9 (P) Zygote进程启动源码分析指南二

         Android 9 Zygote进程启动源码分析指南二 Android 9 (P) 系统启动及进程创建源码分析目录: Android 9 (P)之init进程启动源码分析指南之一 Andro ...

  8. python 多线程和协程结合_一文讲透 “进程、线程、协程”

    本文从操作系统原理出发结合代码实践讲解了以下内容: 什么是进程,线程和协程? 它们之间的关系是什么? 为什么说Python中的多线程是伪多线程? 不同的应用场景该如何选择技术方案? ... 什么是进程 ...

  9. js打印线程id_浅谈python中的多线程和多进程(二)

    原创:hxj7 本文继续分享一个关于python多线程和多进程区别的例子 前文<浅谈python中的多线程和多进程>中我们分享过一个例子,就是分别利用python中的多线程和多进程来解决高 ...

最新文章

  1. 开发各种信息管理系统的标准演示数据都帮你整理好了,少了录入演示\测试\模拟数据的烦恼了[提供下载]...
  2. 结对编程项目作业-结对编项目设计文档
  3. Shell脚本之一 Shell脚本简介
  4. 【CodeForces - 803D】Magazine Ad(二分答案)
  5. STL 容器简介:C++ 容器:顺序性容器、关联式容器和容器适配器
  6. 操作系统之动态库和静态库
  7. mysql(mariadb)重装
  8. springboot整合websocket实现简易版单人聊天
  9. 华为9x升级鸿蒙,荣耀9X升级鸿蒙2.0系统截图曝光:4G内存流畅度照样起飞!
  10. itext汇总 生成pdf
  11. mac使用Java命令运行Java程序
  12. echarts地图实现部分地区高亮
  13. QAM识别算法matlab,16qam调制识别matlab
  14. Opengl入门基础-基础知识
  15. ABAQUS二次开发手册【随书代码使用说明】
  16. [Qualcomm][MSM8909]APQ8009基线上编写一个OpenGl测试程序
  17. 2021小白Python入门学习记录Day3(win10系统、Python3.9、使用Pycharm)python高级数据类型(字符串、列表、元组、字典、集合) 及其操作
  18. 普希金《致凯恩》 与荷尔德林《狄奥提玛》
  19. ubuntu安装pinta(图片编辑器)
  20. python—最大公约数和最小公倍数

热门文章

  1. 厦门大学数学专业考研试题参考解答
  2. php-fpm配置文件,指定session保存目录
  3. 用node.js给图片加水印
  4. HTML标签的分类与特点
  5. Android数据库升级、降级、创建(onCreate() onUpgrade() onDowngrade())的注意点
  6. servlet下根据相对路径找资源
  7. linux中ftp的工作原理,Linux系统学习 十二、VSFTP服务—简介与原理
  8. 帮助中心 开源_如何不获得开源帮助
  9. 开源软件的安全性风险_您的开源安全软件是否安全性较低?
  10. github 创始人_GitHub联合创始人Scott Chacon的视频采访,探讨代码之外的未来