上一篇文章介绍了线程的使用。然而 Python 中由于Global Interpreter Lock(全局解释锁 GIL )的存在,每个线程在在执行时需要获取到这个 GIL ,在同一时刻中只有一个线程得到解释锁的执行, Python 中的线程并没有真正意义上的并发执行,多线程的执行效率也不一定比单线程的效率更高。 如果要充分利用现代多核 CPU 的并发能力,就要使用 multipleprocessing 模块了。
0x01 multipleprocessing
与使用线程的 threading 模块类似,multipleprocessing 模块提供许多高级 API 。最常见的是 Pool 对象了,使用它的接口能很方便地写出并发执行的代码。
from multiprocessing import Pool
def f(x):
return x * x
if __name__ == '__main__':
with Pool(5) as p:
# map方法的作用是将f()方法并发地映射到列表中的每个元素
print(p.map(f, [1, 2, 3]))
# 执行结果
# [1, 4, 9]
关于 Pool 下文中还会提到,这里我们先来看 Process 。
Process
要创建一个进程可以使用 Process 类,使用 start() 方法启动进程。
from multiprocessing import Process
import os
def echo(text):
# 父进程ID
print("Process Parent ID : ", os.getppid())
# 进程ID
print("Process PID : ", os.getpid())
print('echo : ', text)
if __name__ == '__main__':
p = Process(target=echo, args=('hello process',))
p.start()
p.join()
# 执行结果
# Process Parent ID : 27382
# Process PID : 27383
# echo : hello process
进程池
正如开篇提到的multiprocessing模块提供了 Pool 类可以很方便地实现一些简单多进程场景。 它主要有以下接口
apply(func[, args[, kwds]])
执行 func(args,kwds) 方法,在方法结束返回前会阻塞。
apply_async(func[, args[, kwds[, callback[, error_callback]]]])
异步执行 func(args,kwds) ,会立即返回一个 result 对象,如果指定了 callback 参数,结果会通过回调方法返回,还可以指定执行出错的回调方法 error_callback()
map(func, iterable[, chunksize])
类似内置函数 map() ,可以并发执行 func ,是同步方法
map_async(func, iterable[, chunksize[, callback[, error_callback]]])
异步版本的 map
close()
关闭进程池。当池中的所有工作进程都执行完毕时,进程会退出。
terminate()
终止进程池
join()
等待工作进程执行完,必需先调用 close() 或者 terminate()
from multiprocessing import Pool
def f(x):
return x * x
if __name__ == '__main__':