面试题答案
一键面试ThreadPoolExecutor和ProcessPoolExecutor主要功能及适用场景
- ThreadPoolExecutor
- 主要功能:使用线程池来管理和执行异步任务。线程池中的线程会复用,避免了频繁创建和销毁线程带来的开销。线程适合I/O密集型任务,因为线程之间共享内存空间,在进行I/O操作(如网络请求、文件读写等)时,线程可以在等待I/O完成的间隙切换到其他任务执行,提高整体效率。
- 适用场景:适用于I/O密集型任务,例如网络爬虫、文件读写、数据库查询等。在这些场景下,任务大部分时间都在等待I/O操作完成,而不是CPU计算,使用线程可以充分利用等待时间执行其他任务。
- ProcessPoolExecutor
- 主要功能:使用进程池来管理和执行异步任务。每个任务在独立的进程中执行,进程之间相互独立,拥有各自的内存空间。这避免了全局解释器锁(GIL)对CPU计算的限制,使得CPU密集型任务可以真正利用多核CPU的优势。
- 适用场景:适用于CPU密集型任务,如数据处理、科学计算、复杂的算法运算等。这些任务需要大量的CPU计算资源,使用进程可以充分利用多核CPU并行计算,提高计算速度。
使用ThreadPoolExecutor并行执行任务示例代码
import concurrent.futures
import time
def task_function(task_number):
print(f"Task {task_number} started")
time.sleep(1) # 模拟一个耗时操作
print(f"Task {task_number} finished")
return task_number * task_number
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
tasks = [executor.submit(task_function, i) for i in range(5)]
for future in concurrent.futures.as_completed(tasks):
result = future.result()
print(f"Task result: {result}")
在上述代码中:
- 定义了
task_function
函数,该函数模拟了一个耗时1秒的任务,并返回任务编号的平方。 - 使用
ThreadPoolExecutor
创建一个线程池,max_workers
参数设置为3,表示线程池中最多同时有3个线程执行任务。 - 通过列表推导式提交5个任务到线程池。
- 使用
concurrent.futures.as_completed
来迭代已完成的任务,并获取每个任务的执行结果。