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

用户名

此代码(snippet_1)改编自doc中的ThreadPoolExecutor示例

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/ '页面为990869字节' http://www.cnn.com/ '页面为990869字节' http://www.bbc.co.uk/ '页面为990869字节' http://europe.wsj.com/ '页是990869字节后

这段代码是我自己的(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的限制。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么要使用本机函数而不是系统调用?

为什么要使用字符串而不是直接方法调用来触发Redux存储中的操作?

人们为什么说“不要使用place()”?

为什么要使用单独的加载方法而不是构造函数?

为什么使用绑定而不是函数调用?

人们为什么有理由使用React组件的构造函数而不是componentWillMount?

为什么要使用链接到stdin的文件描述符,而不是直接使用stdin?

为什么要使用Python的os模块方法而不是直接执行shell命令?

为什么要使用闭包进行分配,而不是直接为键分配值?

从道具更新状态时,为什么要使用Effect()而不是直接在组件中检查?

人们为什么继续使用xml映射文件而不是注释?

* nix的人们为什么喜欢使用``...''而不是“字符?

为什么从函数调用中检查 undefined 会导致 SSR 错误,而不是在 react 中直接使用 `typeof`?

为什么要使用IHttpActionResult而不是HttpResponseMessage?

为什么要使用isinstance()而不是type()?

为什么要使用uImage而不是zImage

为什么要使用var而不是类型?

为什么要使用jQuery on()而不是click()

为什么要使用beforeRouteEnter而不是挂载?

为什么要使用Runnable而不是Thread?

为什么要使用移位而不是for循环?

为什么要使用资源而不是路由?

为什么要使用Char而不是String?

为什么要使用fillRect而不是translation?

当可以直接访问对象属性时,为什么要使用函数来获取它?

当您可以直接将指针传递给C函数时,为什么要使用memcpy()?

为什么要使用继承和多态性而不是函数模板实例来调用具有相同签名的成员函数?

人们为什么很少使用Java中的匿名构造函数

“ for(;;)”比“ while(TRUE)”更快吗?如果没有,人们为什么要使用它?