有没有多线程的map()函数?

22 投票
6 回答
30050 浏览
提问于 2025-04-15 21:08

我有一个函数,它不会对外部产生影响。现在我想把这个函数应用到一个数组里的每个元素上,然后返回一个包含所有结果的新数组。

请问Python有没有什么方法可以生成所有的结果值呢?

6 个回答

3

Python现在有一个叫做concurrent.futures的模块,这是让map函数在多个线程或者多个进程中工作的最简单方法。

https://docs.python.org/3/library/concurrent.futures.html

12

试试在Python标准库中使用 concurrent.futures.ThreadPoolExecutor.map(从3.2版本开始新增的功能)。

这个用法和 map(func, *iterables) 有点像,但有以下不同:

  • 这里的可迭代对象会立即收集,而不是等到需要的时候才收集;
  • 函数会异步执行,也就是说可以同时调用多个函数。

下面是一个简单的例子(改编自 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):
    # Do something here
    # For example
    with urllib.request.urlopen(url, timeout=timeout) as conn:
      try:
        data = conn.read()
      except Exception as e:
        # You may need a better error handler.
        return b''
      else:
        return data

# We can use a with statement to ensure threads are cleaned up promptly
with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
    # map
    l = list(executor.map(lambda url: load_url(url, 60), URLS))

print('Done.')
18

试试使用 multiprocessing 里的 Pool.map 函数:

http://docs.python.org/library/multiprocessing.html#using-a-pool-of-workers

这并不是严格意义上的多线程,但其实这样更好,因为在 Python 中,多线程会受到 GIL 的严重限制。

撰写回答