2024-09-01
Python
00

目录

1 背景
2 进程池

https://docs.python.org/3/library/multiprocessing.html

1 背景

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自己就是一个服务进程,有点就是灵活,缺点就是慢一些。

2 进程池

进程池肯定是很爽的,使用简单,效果显著。

windows需要multiprocessing.freeze_support()

Linux不需要。

python
import 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() # 主进程等待

运行结果:

python
res此时的结果: [[45]] 此时的时间: 1610254954.318595 进城的PID: 15372 res此时的结果: [[45], [245]] 此时的时间: 1610254954.3205965 进城的PID: 15372 res此时的结果: [[45], [245], [145]] 此时的时间: 1610254954.321597 进城的PID: 16268
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:Dong

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!