编辑
2025-09-21
python
00
请注意,本文编写于 79 天前,最后修改于 79 天前,其中某些信息可能已经过时。

1、CPU密集型 CPython中使用到了GIL,多线程的时候锁相互竞争,且多核优势不能发挥,选用Python多进程效率更 高。即使用ProcessPoolExecutor 2、IO密集型 在Python中适合是用多线程,可以减少多进程间IO的序列化开销。且在IO等待的时候,切换到其他线程 继续执行,效率不错。即ThreadPoolExecutor

ThreadPoolExecutor 和 ProcessPoolExecutor 都是python中的并发执行框架,但它们之间有一些区别: 线程 vs 进程:ThreadPoolExecutor 使用线程池来执行任务,而 ProcessPoolExecutor 使用进程池来执行任务。因为线程是在同一个进程内运行的,所以线程之间共享了进程的内存空间,这意味着线程之间的通信和数据共享比进程更容易。但是,由于 Python 的全局解释器锁(GIL)的存在,同一时刻只有一个线程可以执行 Python 代码,这意味着在 CPU 密集型任务中,多线程并不能真正发挥多核 CPU 的优势。而进程之间是相互独立的,不受 GIL 的限制,可以充分利用多核 CPU 资源。

适用场景:由于 GIL 的限制,ThreadPoolExecutor 更适合于 I/O 密集型任务,如网络请求、文件读写等操作,而 ProcessPoolExecutor 更适合于 CPU 密集型任务,如大量计算、图像处理等操作。

系统资源消耗:由于进程之间是相互独立的,ProcessPoolExecutor 需要更多的系统资源来维护进程之间的通信和数据共享,而 ThreadPoolExecutor 只需要维护线程之间的通信和数据共享,所以在系统资源有限的情况下,ThreadPoolExecutor 更加适合。

ThreadPoolExecutor代码示例

python
from concurrent.futures import ThreadPoolExecutor import concurrent def func(): pass with ThreadPoolExecutor(max_workers=15) as executor: tasks = {} case_number = 0 finished = 0 for idx, row in df.iterrows(): tasks[executor.submit(func, session, row['col1'])] = (row['col2'], row['col3']) case_number += 1 split_part_num = case_number // 200 for future in concurrent.futures.as_completed(tasks): cate_id_list, cate_name_list, confidence_list = future.result() request_id, row_list = tasks[future] name, code = tasks[future] if len(cate_name_list.split(';')) >= 1: res_cate_name = cate_name_list.split(';')[0] res_cate_id = cate_id_list.split(';')[0] # res_confidence = confidence_list.split(';')[0] res_confidence = confidence_list[0] cate_path = back_tree[res_cate_id] res_data.append([name, code, res_cate_id, res_cate_name, cate_path, res_confidence]) else: res_data.append(['', '', '', '']) finished += 1 if finished % split_part_num == 0: print("【 total finished:{}% 】".format(0.5 * finished / split_part_num)) print('done')

本文作者:brucewu

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!