https://docs.python.org/3/library/multiprocessing.html
python由于Global Interpreter Lock 的原因,多线程并不是我们想的那种CPU调度的多线程,在python中开了多线程其实也是一个单进程。
针对CPU密集型(CPU-bound)的任务,比如计算气象数据,多线程和多进程调用多个CPU核心并行,能有效减少任务计算时间,提高实时性,但python的多线程是不ok的。
针对IO密集型(I/O bound)的任务,比如爬虫,多线程和多进程也是OK的,python的多线程显然也是ok的。
进程会占用更多资源,比如主进程开一个子进程,子进程会把主进程的变量啥的复制一份,这也导致进程之间通信和线程不一样。多线程的时候,给一个全局列表进去还能线程安全;多进程的时候,子进程只会把主进程的全局列表复制一份带入,修改的也是修改子进程的。所以需要类似信号、管道、消息队列、共享内存的东西来进行,python multiprocessing有消息队列、管道、共享内存,优点是快,缺点是不太灵活(存储类型和运行机制),python multiprocessing提供了一个更高级的封装类Manager
来专门处理这个事情,Manager
自己就是一个服务进程,有点就是灵活,缺点就是慢一些。
进程池肯定是很爽的,使用简单,效果显著。
windows需要multiprocessing.freeze_support()
Linux不需要。
pythonimport multiprocessing
import time
import os
def func1(inputdata, res):
res.append([sum(inputdata)])
print("res此时的结果: ", res)
print("此时的时间: ", time.time())
print("进城的PID: ", os.getpid())
if __name__ == '__main__':
multiprocessing.freeze_support()
res = multiprocessing.Manager().list() # 通信
inputdata = [i for i in range(100)] # 随便弄点数
p = multiprocessing.Pool(2) # 创建一个包含2个进程的进程池
p.apply_async(func=func1, args=(inputdata[0:10], res,)) # 往池子里加一个异步执行的子进城
p.apply_async(func=func1, args=(inputdata[10:20], res,)) # 往池子里加一个异步执行的子进程
p.apply_async(func=func1, args=(inputdata[20:30], res,)) # 往池子里加一个异步执行的子进程
p.close() # 等子进程执行完毕后关闭进程池
p.join() # 主进程等待
运行结果:
pythonres此时的结果: [[45]]
此时的时间: 1610254954.318595
进城的PID: 15372
res此时的结果: [[45], [245]]
此时的时间: 1610254954.3205965
进城的PID: 15372
res此时的结果: [[45], [245], [145]]
此时的时间: 1610254954.321597
进城的PID: 16268
本文作者:Dong
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!