协程/进程/线程资料收集

协程(Coroutine), 多线程(Thread), 多进程(Multiprocessing)资料繁多, 学无止境, 就集中在这一篇收集贴中. 便于查阅学习

自己的理解

  • 协程, 任务之间不是竞争关系, 而是协作关系, 需要每个任务都需要有一颗舍己为公的心!
    • 大家排队喝水, 喝到差不多就自己让给下一个人, 自己再去排队! 可按照优先级来插队的.
    • 遇到不讲道理的人, 那这个机制就失效了. 因为没有抢占, 大家都只会默默等待…
    • 优点, 任务切换的代价非常小. 由于没有抢占, 也就没有复杂的临界区问题. 锁的问题也变得简单.
    • 缺点, 这个世界上总有不讲理的人, 所以, 大型任务和系统不敢这么用…
    • 单片机开发是非常适合使用协程的! (资源有限, 需要减小任务切换的开销. 任务可控, 意味着易于协作)
    • python 下可用 gevent.
  • 多线程, 任务之间是竞争关系, 高优先级优先执行, 同时又有时间片限制, 避免高优先级任务霸占CPU
    • 谁强谁喝水, 不过旁边有个管理员, 哪个家伙喝水时间太久了, 就会把他给跩一边去, 大家重新来抢.
    • 线程是共享内存的, 理解为这些水来自于同一个自来水厂(这个水厂有毒的话, 谁了逃不了),
    • 多核就是多个水龙头, 同一时刻可以有多个人在喝水.
    • 优点, 任务的开销比进程小(因为共享内存), 通讯方式多样. 加个水龙头和造个水厂的区别!!!
    • 缺点, 一大帮自私又不讲理的人在一起总是很难管理的… 需要各种锁机制来维持和谐共处…
    • python的多线程, 由于GIL机制的存在, 是无法利用多核的. (意味着不适用于CPU密集型任务)
    • python有一个类进程版本的线程池 multiprocessing.pool.ThreadPool, 可以获取返回值
      由于本质是线程, Windows下terminate方法是没有用的.
  • 多进程, 任务之间是竞争关系, 任务之间的数据全部隔离, 没有共享.
    • 进程是资源分配的基本单位. 进程包含线程, 线程共用进程的资源.
    • 进程比线程安全性更高, 因为拥有独立的内存块(独立水厂供水)
    • 进程的建立和调度比线程更费时间和资源
    • 进程间的数据共享和交换很麻烦. (python例子中, 进程内 print 不会打印, 参数传递需要可以pickle)
    • python 下推荐使用 multiprocessing.pool.Pool. 可以获取返回值.
  • 进程和线程以及多核
    • 操作系统必须有一个进程, 创建进程时, 会分配好供这个进程使用的内存和上下文环境.
    • 线程依赖于进程, 多线程运行于同一个进程下面, 会共享同一个进程的内存.
    • 事实上, 线程是最难写好的一种多任务方式(因为共享内存).
    • 以android为例,
      • android的每一个应用就是一个linux进程, 所以写的再烂的应用也不会导致整个android系统崩溃.
      • 应用内支持多线程, 也事实上都对应到linux的线程, 这些线程运行在分配好的linux进程中.
    • 进程和线程的概念和单核还是多核一点关系都没有! 先理解好单核再说, 真正涉及到CPU密集型任务时, 再考虑多核优化…

优缺点比较

  • 协程具有进程和线程各自的优点. 但其缺点是需要任务间自己来协作调度(很容易写成阻塞等待), 这一点直接导致了通用性很差.
  • 多线程还是多进程的选择及区别, 比较全面的一篇文章!
    • 本文也有一个转字, 应该是综合了多种搜素结果写出来的一篇博文. 有结论, 有实验代码和过程
    • 鱼还是熊掌:浅谈多进程多线程的选择
    • 1.进程与线程
    • 一、重复周丽论文实验步骤
    • 二、增加并发数量的实验
    • 三、增加每进程/线程的工作强度的实验
    • 四、多进程和多线程在创建和销毁上的效率比较
    • 五、双核系统重复周丽论文实验步骤
    • 六、并发服务的不可测性
对比维度 多进程 多线程 总结
数据共享、同步 数据共享复杂,需要用IPC;数据是分开的,同步简单 因为共享进程数据,数据共享简单,但也是因为这个原因导致同步复杂 各有优势
内存、CPU 占用内存多,切换复杂,CPU利用率低 占用内存少,切换简单,CPU利用率高 线程占优
创建销毁、切换 创建销毁、切换复杂,速度慢 创建销毁、切换简单,速度很快 线程占优
编程、调试 编程简单,调试简单 编程复杂,调试复杂 进程占优
可靠性 进程间不会互相影响 一个线程挂掉将导致整个进程挂掉 进程占优
分布式 适应于多核、多机分布式;如果一台机器不够,扩展到多台机器比较简单 适应于多核分布式 进程占优

资料集

  • Python Multithreaded Programming

    • Python多线程入门教程, 有详细的说明, 源代码及运行结果.
    • 主要有3个示例, 多线程, 多线程同步, 使用Queue来通讯
  • Python 多线程

    • 介绍了Python多线程的状态, 类型
    • 线程的创建, 合并(join), 同步, 锁(Lock, 死锁, RLock), 其它IPC
    • 将子线程设置后台线程(setDaemon), 让子线程随主线程一起结束.
    • 提了一下Python的GIL, 参考资料中的一篇对此做了很好的说明: python 线程,GIL 和 ctypes
  • Python线程同步机制: Locks, RLocks, Semaphores, Conditions, Events和Queues

    • 线程(Threading)
    • 锁(Lock)
    • 可重入锁(RLock)
    • 条件(Condition)
    • 信号量(Semaphore)
    • 事件(Event)
    • 队列(Queue), 重点推荐
  • 理解 Python 中的多线程

    • 示例1, 请求五个不同的url. 比较了单线程和多线程性能上的差别
    • 示例2, 全局变量的线程安全问题(race condition). BUG版和修改版
    • 示例3, 多线程环境下的原子操作. BUG版和修改版
    • 示例4, Python多线程简易版:线程池 threadpool
    • 附上了很多参考和推荐阅读的资料!
  • 线程池 threadpool (需安装)

  • Python 多线程教程:并发与并行

    • 讲了多线程, 多进程, 以及分布式任务.
    • 原作者已下载网络图片来说明问题, 转发者为了便于测试和理解, 简化了代码.
    • 1, 单线程执行. 花了19.4秒去下载91张图片
    • 2, 多线程. 下载时间变成了4.1秒. 并说明了为何有GIL的情况下, 多线程仍然是有效的(因为是IO密集型的任务)
    • 3, 多进程. 优点, 避免了GIL, 适用于CPU密集型任务. 缺点, 耗内存!
    • 4, 分布式任务. 提了一下RQCelery
    • 5, 总结: IO密集型,多线程或多进程. CPU密集型, 多进程. 网络应用, 分布式任务
    • 6, 并发、并行区别与联系. 并发, 一个人按优先级处理多件事情(任一时刻只能做一件事情). 并行, 有多个人各自做事(多核多任务).
  • 进程池 multiprocessing.Pool 以及 multiprocessing.pool.ThreadPool

  • 浅谈 python multiprocessing(多进程)下如何共享变量

    • 1, 抛出了一个多进程的问题.
    • 2, python 多进程共享变量的几种方式
    • 3, 多进程的问题远不止这么多:数据的同步. (需要Lock)
    • 4, 总结为: 多进程最好还是用IPC(message之类的). 如果一定要用共享变量, 那也是可以的…
  • Python之路:(十五)进程、线程和协程

    • Python线程, 线程锁(Lock, Rlock), 其它IPC, 线程池
    • Python进程, 进程数据共享, 进程IPC. (Python Windows下是可以用进程的, 只是不支持fork)
    • Python协程, greenlet(主动切换), gevent(遇到IO操作, 自动切换).
  • gevent程序员指南

    • 核心部分, 较为详细的介绍了 gevent 的原理和使用方式.
    • 数据结构, 介绍了协程之间的通讯工具
    • 真实世界的应用, 几个实际应用的例子

原创于 DRA&PHO