Loading... # 引言 因为python天生的GIL锁机制的影响,导致python应用无法跑满所有CPU核心,可以采用多进程的方式来"压榨CPU资源"。 # 代码 ```python from concurrent.futures import as_completed, ProcessPoolExecutor import datetime import time import json def calc(a, b): rst = {"start": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")} time.sleep(1) # 模拟耗时计算 rst['result'] = a * b rst['end'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") return rst if __name__ == '__main__': future_list = [] result_list = [] with ProcessPoolExecutor(max_workers=4) as executor: # 最大进程数 for i in range(100): future_list.append(executor.submit(calc, i, i + 1)) # 提交到任务队列 for future in as_completed(future_list): # 获取结果 result_list.append(future.result()) print(json.dumps(result_list, indent=4)) ``` ## 执行结果 ![image.png](https://www.zunmx.top/usr/uploads/2024/12/3112280269.png) ```json [ { "start": "2024-12-13 13:48:29", "result": 0, "end": "2024-12-13 13:48:30" }, { "start": "2024-12-13 13:48:29", "result": 6, "end": "2024-12-13 13:48:30" }, { "start": "2024-12-13 13:48:29", "result": 2, "end": "2024-12-13 13:48:30" }, { "start": "2024-12-13 13:48:29", "result": 12, "end": "2024-12-13 13:48:30" }, { "start": "2024-12-13 13:48:30", "result": 20, "end": "2024-12-13 13:48:31" }, { "start": "2024-12-13 13:48:30", "result": 30, "end": "2024-12-13 13:48:31" }, { "start": "2024-12-13 13:48:30", "result": 42, "end": "2024-12-13 13:48:31" }, { "start": "2024-12-13 13:48:30", "result": 56, "end": "2024-12-13 13:48:31" }, { "start": "2024-12-13 13:48:31", "result": 72, "end": "2024-12-13 13:48:32" }, { "start": "2024-12-13 13:48:31", "result": 90, "end": "2024-12-13 13:48:32" }, { "start": "2024-12-13 13:48:31", "result": 110, "end": "2024-12-13 13:48:32" }, { "start": "2024-12-13 13:48:31", "result": 132, "end": "2024-12-13 13:48:32" } ] ``` 根据结果可知,每四个任务同时执行,组成了任务队列。 # 问答区 ## 为什么不使用多线程? Python的GIL使得在多线程中,同时只能有一个线程占用CPU核心。即使有多个核,也无法同时运行许多线程。因此,为了利用多核的能力,应该使用多过程。 ## 什么场景下可以考虑使用多线程? 在不是在CPU上计算而是计算的延时在外部资源(如数据库调用,网络连接)时,python仅需要等待结果的场景。 ## 既然多进程可以"使用多核",能不能把多线程全部替代成多进程 理论上是可以的,但是对于系统资源消耗上来说,在启动和销毁进程时,也存在一定的资源消耗,如果某个任务很容易,线程可以解决的,应采用线程的方式,这样对于资源消耗也会小很多。 ## 报错 ```shell RuntimeError: An attempt has been made to start a new process before the current process has finished its bootstrapping phase. This probably means that you are not using fork to start your child processes and you have forgotten to use the proper idiom in the main module: if __name__ == '__main__': freeze_support() ... The "freeze_support()" line can be omitted if the program is not going to be frozen to produce an executable. To fix this issue, refer to the "Safe importing of main module" section in https://docs.python.org/3/library/multiprocessing.html ``` 在创建子进程时,会重新运行主脚本文件。这可能会导致循环导入或意外的行为,说简单点就是需要从__main__入口进入, © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏