利用Python的util模块进行并发编程实践
并发编程是指在同一时间内执行多个任务的能力,这可以大大提高程序的运行效率。Python的concurrent.futures模块提供了一种简单且易于使用的方式来实现并发编程。
concurrent.futures模块提供了两个类,ThreadPoolExecutor和ProcessPoolExecutor,用于实现线程和进程的并发执行。这两个类都实现了Python的Executor接口,因此在使用时使用方法是相似的。
首先,我们需要导入必要的模块:
import concurrent.futures import time
下面是一个使用ThreadPoolExecutor的例子:
def do_something(seconds):
print(f'Sleeping {seconds} second(s) ...')
time.sleep(seconds)
return f'Done sleeping {seconds} second(s)'
if __name__ == '__main__':
start_time = time.perf_counter()
with concurrent.futures.ThreadPoolExecutor() as executor:
# 提交任务,并获取到一个future对象
f1 = executor.submit(do_something, 1)
f2 = executor.submit(do_something, 2)
# 获得future对象的结果
print(f1.result())
print(f2.result())
end_time = time.perf_counter()
print(f'Finished in {end_time - start_time} seconds')
输出:
Sleeping 1 second(s) ... Sleeping 2 second(s) ... Done sleeping 1 second(s) Done sleeping 2 second(s) Finished in 2.002279645 seconds
在这个例子中,我们使用了ThreadPoolExecutor来创建一个线程池,并通过submit方法提交了两个任务。submit方法返回一个Future对象,代表了任务的执行结果。
我们可以使用result方法获取到任务的返回结果。注意,result方法是一个阻塞调用,也就是说,如果任务还没有完成,它会阻塞直到任务完成。
下面是使用ProcessPoolExecutor的例子:
def do_something(seconds):
print(f'Sleeping {seconds} second(s) ...')
time.sleep(seconds)
return f'Done sleeping {seconds} second(s)'
if __name__ == '__main__':
start_time = time.perf_counter()
with concurrent.futures.ProcessPoolExecutor() as executor:
# 提交任务,并获取到一个future对象
f1 = executor.submit(do_something, 1)
f2 = executor.submit(do_something, 2)
# 获得future对象的结果
print(f1.result())
print(f2.result())
end_time = time.perf_counter()
print(f'Finished in {end_time - start_time} seconds')
输出与上一个例子相同。
需要注意的是,ThreadPoolExecutor和ProcessPoolExecutor之间的差异在于,在使用ProcessPoolExecutor时,我们需要在一个if __name__ == '__main__':语句块中运行主函数,以防止创建子进程时出错。
总结:
- 利用concurrent.futures模块可以很容易地实现并发编程。
- ThreadPoolExecutor适用于I/O密集型任务,而ProcessPoolExecutor适用于CPU密集型任务。
- 使用submit方法提交任务,并使用result方法获取任务的执行结果。
以上是利用Python的concurrent.futures模块进行并发编程的实践,通过使用线程或进程池,我们可以通过异步执行多个任务来提高程序的运行效率。
