python--多进程 & 协程
资料来源:
https://docs.python.org/zh-cn/3/library/multiprocessing.html
https://www.liaoxuefeng.com/wiki/1016959663602400/1017628290184064更新
1
2021.04.16 初始
导语
python 因为 gil 锁的存在,所以多线程算是鸡肋.若要完全利用 cpu 多进程+协程是推荐的方式.
但是从使用来看,python 支持协程的库还太少,也不能简单的将串行的库改写为支持协程的,因此有些无奈…😔…
先补充有关多进程的内容了,python 协程或许还没有 get 到正确的使用方法.
多进程
资料来源于廖雪峰教程/官方文档.
linux 上创建进程是个著名的调用 fork
,但是 win 上并不通用.因此 python 提供了 multiprocessing
库,保证跨平台.
每一个进程被描述成一个 Process
类对象,启动时调用 start
方法.join
这里是等待子进程结束.
1 | from multiprocessing import Process |
进程池
手动创建 N 多进程很冗余,python 提供了 Pool
类,实现了类似进程池的用法.
1 | from multiprocessing import Pool |
apply_async
导入执行函数.
Pool(4)
最好与机器的 cpu 线程数相同.
close
执行后无法再加入新的进程.
进程间通信
multiprocessing
提供了两种近似方法, Queue
队列 和 Pipe()
管道.
Queue
是线程和进程安全的,多进程随意读写.
1 | from multiprocessing import Process, Queue |
Pipe()
管道,默认是全双工的 ,但是不支持多进程/线程竞争读 or 写.
1 | from multiprocessing import Process, Pipe |
进程间同步
并不推荐在多进程间使用锁,但是 multiprocessing
提供了类似 替代
进程间共享状态
因为暂时没有用到,就不详述了.
详情见 进程间共享状态
编程指导
来着官方文档的 多进程编程指导,只摘取一些记录了.
start方法
避免共享状态.
- 避免大量进程间通信
- 通信以
multiprocessing
提供的队列管道最佳 .
继承优先于序列化/反序列化
- 通常需要避免通过队列/管道发送对象,因此子进程直接从父进程继承这些对象更优先.
join
- 需要避免僵尸进程…无限等待…
- join 进程池时,必须非常小心共享资源,非常容易造成死锁.
尽力避免
Process.terminate
,一旦杀掉进程,其相关的所有资源将不可用,可能造成未知问题.
协程
官方文档: 协程与任务
async/await 语法糖是 python 3.6 以后引入的,因此搜索协程资料稍早一点会有混乱.
更多资料和食用,待后续 get 协程重点再补充.
目前使用协程并没有给程序带来收益.因为用到的库除了 sqlite 外,其他都不支持 协程调用,同时使用了内存盘,sqlite 上协程带来的一点收益也非常不明显.
一些协程资料
https://mp.weixin.qq.com/s?__biz=Mzg3MjU3NzU1OA==&mid=2247495856&idx=1&sn=144acd0252a09c96991cabcdc0f80d1f&source=41#wechat_redirect
结语
py 协程并没有像初次接触 kotlin 协程那样经验,或许还需要等待更熟悉 py 时才能领略吧.
多进程已经可以把 cpu 跑到 100%,但是这样依旧跑了超过 1 个小时,数据处理阶段 尚可接受,但是这样跑算法 ~ 实在是无法接受…
或许考虑换 go ?