下面我将详细讲解如何使用 Python 实现线程池并给出示例代码。本攻略将分为以下几个部分:
- 讲解什么是线程池
- 如何用 Python 实现线程池
- 两个示例说明如何使用线程池
1. 线程池是什么?
一个线程池是一个线程队列,线程池通过重用线程来实现线程的可复用,从而减少了创建和销毁线程的开销。线程池内的线程可以被重复使用来执行多个并发任务。
一个线程池通常有两个重要的参数:一个是线程数,另一个是任务队列。线程池会创建指定数量的线程,这些线程会从任务队列中取出任务并执行。当线程执行完任务后,会再次回到任务队列,等待新的任务到来。
2. 如何用 Python 实现线程池
在 Python 中,我们可以使用 ThreadPoolExecutor 来实现线程池。ThreadPoolExecutor 是 python3 内置的线程池包。
线程池的创建只需要两步:
- 创建线程池对象
- 向线程池中添加任务
下面是一个简单的线程池示例代码:
import concurrent.futures
import time
def worker(n):
print('{} start'.format(n))
time.sleep(1)
print('{} end'.format(n))
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
for i in range(3):
executor.submit(worker, i)
代码中使用了 concurrent.futures 模块的 ThreadPoolExecutor 类创建了一个最大线程数为 3 的线程池,并向线程池中添加了 3 个任务。
示例代码输出的结果如下:
0 start
1 start
2 start
0 end
1 end
2 end
3. 两个示例说明如何使用线程池
示例 1:计算斐波那契数列
下面是一个使用线程池计算斐波那契数列的示例代码:
import concurrent.futures
def fib(n):
if n <= 2:
return 1
return fib(n - 1) + fib(n - 2)
def main():
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
results = [executor.submit(fib, n) for n in range(1, 11)]
for future in concurrent.futures.as_completed(results):
print(future.result())
if __name__ == '__main__':
main()
代码中,我们使用线程池并发地计算斐波那契数列。首先,我们定义了一个求斐波那契数列第 n 项的函数 fib(n)。然后,我们使用线程池并发地计算斐波那契数列前 10 项,并输出计算结果。
示例代码输出的结果如下:
1
1
2
3
5
8
13
21
34
55
示例 2:下载网络图片
下面是一个使用线程池下载网络图片的示例代码:
import concurrent.futures
import urllib.request
def download_image(url):
with urllib.request.urlopen(url) as u:
with open(url.split('/')[-1], 'wb') as f:
f.write(u.read())
print('{} downloaded'.format(url))
def main():
urls = [
'https://www.python.org/static/apple-touch-icon-144x144-precomposed.png',
'https://www.python.org/static/apple-touch-icon-120x120-precomposed.png',
'https://www.python.org/static/apple-touch-icon-114x114-precomposed.png',
'https://www.python.org/static/apple-touch-icon-72x72-precomposed.png'
]
with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
results = [executor.submit(download_image, url) for url in urls]
for future in concurrent.futures.as_completed(results):
pass
if __name__ == '__main__':
main()
代码中,我们使用线程池并发地下载了 4 张图片。首先,我们定义了一个下载图片的函数 download_image(url)。然后,我们使用线程池并发地下载图片,并输出下载完成的图片的 url。
示例代码输出的结果如下:
https://www.python.org/static/apple-touch-icon-144x144-precomposed.png downloaded
https://www.python.org/static/apple-touch-icon-72x72-precomposed.png downloaded
https://www.python.org/static/apple-touch-icon-114x114-precomposed.png downloaded
https://www.python.org/static/apple-touch-icon-120x120-precomposed.png downloaded
以上就是使用 Python 实现线程池的完整攻略了。Hope that helps!
本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!