Python多线程与多进程

进程与线程

Python封装了多进程与多线程库,ThreadPool和DummyPool属于多线程,ProcessPool属于多进程。

# 多线程
from multiprocessing.pool import ThreadPool
from multiprocessing.dummy import Pool as DummyPool
# 多进程
from multiprocessing import Pool as ProcessPool

计算密集型任务使用多进程,IO密集型任务使用多线程。

Python有GIL(全局解释器锁),每个CPU在同一时间内只能执行一个线程。

  • CPU密集型任务使用多进程:
    • Python2.x使用ticks计数达到100即释放GIL,导致CPU密集型任务在for循环等任务中频繁切换线程,消耗资源。
    • Python3.x不使用ticks计数而是使用计时,对CPU密集型任务更友好了,但是没有解决GIL导致的每个CPU在同一时间内只能执行一个线程的问题,所以效率依然不高。
  • IO密集型任务使用多线程:
    • 多线程在遇到IO时自动切换线程,不浪费CPU资源。

并行:同时处理多个任务
并发:以切片式分段串行处理多任务

据说,对于多进程而言,有return会比没有return慢很多很多,对于多线程却只会慢一点点

通用示例

def func(param):
    pass
    return ...

pool = ThreadPool(4)
res = pool.map(func, iterable)
pool.close() #置状态,不接受新的输入
pool.join() #主线程等待子线程退出

tqdm进度条 与 多线程/多进程的结合 p_tqdm

参考 https://github.com/swansonk14/p_tqdm

pip install p_dqdm
from p_tqdm import p_imap

def add(a, b):
    return a + b

iterator = p_imap(add, ['1', '2', '3'], ['a', 'b', 'c'])

for result in iterator:
    print(result) # prints '1a', '2b', '3c'

对于输入数据中存在不需要迭代的对象,使用partial

from functools import partial

l1 = ['1', '2', '3']
l2 = ['a', 'b', 'c']

def add(a, b, c=''):
    return a + b + c

added = p_map(partial(add, c='!'), l1, l2)
# added == ['1a!', '2b!', '3c!']
posted @ 2020-03-31 23:38  yoqitan  阅读(440)  评论(0编辑  收藏  举报