python - 为什么人们会使用 ThreadPoolExecutor 而不是直接函数调用?

标签 python

此代码(snippet_1)改编自 ThreadPoolExecutor Example in doc

import concurrent.futures
import urllib.request

URLS = ['http://www.foxnews.com/',
        'http://www.cnn.com/',
        'http://europe.wsj.com/',
        'http://www.bbc.co.uk/']

# Retrieve a single page and report the URL and contents
def load_url(url, timeout):
    with urllib.request.urlopen(url, timeout=timeout) as conn:
        return conn.read()

# We can use a with statement to ensure threads are cleaned up promptly
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
    # Start the load operations and mark each future with its URL
    future_to_url = {executor.submit(load_url, url, 60): url for url in URLS}
    for future in concurrent.futures.as_completed(future_to_url):
        url = future_to_url[future]
        print('%r page is %d bytes' % (url, len(data)))

print('after')

效果很好,并且得到

'http://www.foxnews.com/' page is 990869 bytes 'http://www.cnn.com/' page is 990869 bytes 'http://www.bbc.co.uk/' page is 990869 bytes 'http://europe.wsj.com/' page is 990869 bytes after

此代码是我自己的代码 (snippet_2),用于通过直接函数调用实现相同的工作。

import urllib.request

URLS = ['http://www.foxnews.com/',
        'http://www.cnn.com/',
        'http://europe.wsj.com/',
        'http://www.bbc.co.uk/']
for url in URLS:
    with urllib.request.urlopen(url, timeout=60) as conn:
        print('%r page is %d bytes' % (url, len(data)))

print('after')

snippet_1 似乎更常见,但为什么呢?

最佳答案

当您从网络读取内容时,您的应用程序可能会花费大部分时间等待回复。

通常,CPython(您可能正在使用的 Python 实现)内的全局解释器锁可确保一次只有一个线程正在执行 Python 字节码。

但是当等待 I/O(包括网络 I/O)时,GIL 被释放,为其他线程提供运行的机会。这意味着多个读取有效地并行运行,而不是一个接一个地运行,从而缩短了整体执行时间。

对于少数 URI 来说,这不会产生太大影响。但是您使用的 URI 越多,它就越引人注目。

因此,ThreadPoolExecutor 主要用于并行运行 I/O 操作。另一方面,ProcessPoolExecutor 对于并行运行 CPU 密集型任务非常有用。由于它使用多个进程,因此 GIL 的限制不适用。

关于python - 为什么人们会使用 ThreadPoolExecutor 而不是直接函数调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57537215/

相关文章:

python - 将组织信息添加到 Google Contacts API

Python:使用 cURL 获取重定向 url

python - PySide + QGraphicsScene 仅显示为黑色

python - 如何使用通过 webdriver_manager 安装的 ChromeDriver 更改 Google Chrome UserAgent

python - 内核在 Jupyter Notebook 中自动完成(制表符)的时间太长

python - 无法从 linux、c++ 执行 "main(filename)"python 脚本的 "my_script"函数; pModule = PyImport_Import(pName);返回空

python - 批量大小和训练时间

python - 我无法将我在 Seaborn 中的线图的 xticks 设置为相应小时的值

python - 如何分组并计算 Pandas 的概率

python - 使用嵌套列表打印 5x5 数字