concurrent.futures.md
1> **Источник:** https://python-all.ru/3.13/library/concurrent.futures.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `concurrent.futures` – Запуск параллельных задач89Добавлено в версии 3.2.1011**Исходный код:** [Lib/concurrent/futures/thread.py](https://python-all.ru/src/3.13/Lib/concurrent/futures/thread.py) и [Lib/concurrent/futures/process.py](https://python-all.ru/src/3.13/Lib/concurrent/futures/process.py)1213---1415Модуль `concurrent.futures` предоставляет высокоуровневый интерфейс для асинхронного выполнения вызываемых объектов.1617Асинхронное выполнение может выполняться с помощью потоков, используя [`ThreadPoolExecutor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor), или отдельных процессов, используя [`ProcessPoolExecutor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.ProcessPoolExecutor). Оба реализуют один и тот же интерфейс, определяемый абстрактным классом [`Executor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Executor).1819[`concurrent.futures.Future`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Future) не следует путать с [`asyncio.Future`](https://python-all.ru/3.13/library/asyncio-future.html#asyncio.Future), который предназначен для использования с [`asyncio`](https://python-all.ru/3.13/library/asyncio.html#module-asyncio) задачами и корутинами. Обратитесь к документации [asyncio.Future](https://python-all.ru/3.13/library/asyncio-future.html) для подробного сравнения двух.2021[Доступность](https://python-all.ru/3.13/library/intro.html#availability): не WASI.2223Этот модуль не работает или недоступен на WebAssembly. Подробнее см. [платформы WebAssembly](https://python-all.ru/3.13/library/intro.html#wasm-availability).2425## Объекты исполнителя2627#### `class concurrent.futures.Executor`2829Абстрактный класс, предоставляющий методы для асинхронного выполнения вызовов. Его не следует использовать напрямую, а через его конкретные подклассы.3031#### `submit(fn, /, *args, **kwargs)`3233Планирует выполнение вызываемого объекта *fn* как `fn(*args, **kwargs)` и возвращает объект [`Future`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Future), представляющий выполнение вызываемого объекта.3435```python36with ThreadPoolExecutor(max_workers=1) as executor:37 future = executor.submit(pow, 323, 1235)38 print(future.result())39```4041#### `map(fn, *iterables, timeout=None, chunksize=1)`4243Аналогично [`map(fn, *iterables)`](https://python-all.ru/3.13/library/functions.html#map), но:4445- *Итерируемые объекты* собираются немедленно, а не лениво;46- *fn* выполняется асинхронно, и несколько вызовов *fn* могут выполняться одновременно.4748Возвращаемый итератор возбуждает [`TimeoutError`](https://python-all.ru/3.13/library/exceptions.html#TimeoutError), если вызван [`__next__()`](https://python-all.ru/3.13/library/stdtypes.html#iterator.__next__) и результат недоступен через *timeout* секунд после исходного вызова `Executor.map()`. *timeout* может быть целым числом или числом с плавающей запятой. Если *timeout* не указан или равен `None`, время ожидания не ограничено.4950Если вызов *fn* возбуждает исключение, то это исключение будет возбуждено при получении его значения из итератора.5152При использовании [`ProcessPoolExecutor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.ProcessPoolExecutor) этот метод разбивает *итерируемые объекты* на несколько частей, которые передаёт в пул как отдельные задачи. (Примерный) размер этих частей можно задать, установив *chunksize* в положительное целое число. Для очень длинных итерируемых объектов использование большого значения *chunksize* может значительно повысить производительность по сравнению со значением по умолчанию, равным 1. С [`ThreadPoolExecutor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor) параметр *chunksize* не влияет на выполнение.5354Изменено в версии 3.5: Добавлен аргумент *chunksize*.5556#### `shutdown(wait=True, *, cancel_futures=False)`5758Сообщает исполнителю, что он должен освободить все используемые ресурсы, когда текущие ожидающие future завершат выполнение. Вызовы [`Executor.submit()`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Executor.submit) и [`Executor.map()`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Executor.map) после shutdown приведут к возбуждению [`RuntimeError`](https://python-all.ru/3.13/library/exceptions.html#RuntimeError).5960Если *wait* равен `True`, то этот метод не вернёт управление, пока все ожидающие future не завершат выполнение и ресурсы, связанные с исполнителем, не будут освобождены. Если *wait* равен `False`, то метод вернёт управление немедленно, а ресурсы, связанные с исполнителем, будут освобождены, когда все ожидающие future завершат выполнение. Независимо от значения *wait*, вся программа Python не завершится, пока все ожидающие future не завершат выполнение.6162Если *cancel\_futures* равен `True`, этот метод отменит все ожидающие future, которые исполнитель ещё не начал выполнять. Любые future, которые уже завершены или выполняются, отменены не будут, независимо от значения *cancel\_futures*.6364Если и *cancel\_futures*, и *wait* равны `True`, то все future, которые исполнитель начал выполнять, будут завершены до возврата из этого метода. Остальные future отменяются.6566Можно избежать явного вызова этого метода, если использовать исполнитель как [менеджер контекста](https://python-all.ru/3.13/glossary.html#term-context-manager) через оператор [`with`](https://python-all.ru/3.13/reference/compound_stmts.html#with), который завершит работу `Executor` (ожидая, как если бы `Executor.shutdown()` был вызван с *wait*, установленным в `True`):6768```python69import shutil70with ThreadPoolExecutor(max_workers=4) as e:71 e.submit(shutil.copy, 'src1.txt', 'dest1.txt')72 e.submit(shutil.copy, 'src2.txt', 'dest2.txt')73 e.submit(shutil.copy, 'src3.txt', 'dest3.txt')74 e.submit(shutil.copy, 'src4.txt', 'dest4.txt')75```7677Изменено в версии 3.9: Добавлен *cancel\_futures*.7879## ThreadPoolExecutor8081[`ThreadPoolExecutor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor) – подкласс [`Executor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Executor), использующий пул потоков для асинхронного выполнения вызовов.8283Взаимоблокировки могут возникать, когда вызываемый объект, связанный с [`Future`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Future), ожидает результаты другого `Future`. Например:8485```python86import time87def wait_on_b():88 time.sleep(5)89 print(b.result()) # b никогда не завершится, потому что он ожидает a.90 return 59192def wait_on_a():93 time.sleep(5)94 print(a.result()) # a никогда не завершится, потому что он ожидает b.95 return 69697executor = ThreadPoolExecutor(max_workers=2)98a = executor.submit(wait_on_b)99b = executor.submit(wait_on_a)100```101102И:103104```python105def wait_on_future():106 f = executor.submit(pow, 5, 2)107 # Это никогда не завершится, потому что есть только один рабочий поток и108 # он выполняет эту функцию.109 print(f.result())110111executor = ThreadPoolExecutor(max_workers=1)112future = executor.submit(wait_on_future)113# Примечание: вызов future.result() также приведёт к взаимоблокировке, потому что114# единственный рабочий поток уже ожидает wait_on_future().115```116117#### `class concurrent.futures.ThreadPoolExecutor(max_workers=None, thread_name_prefix='', initializer=None, initargs=())`118119Подкласс [`Executor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Executor), который использует пул не более чем из *max\_workers* потоков для асинхронного выполнения вызовов.120121Все потоки, поставленные в очередь `ThreadPoolExecutor`, будут присоединены до того, как интерпретатор сможет завершиться. Обратите внимание, что обработчик выхода, который это делает, выполняется *до* любых обработчиков выхода, добавленных с помощью `atexit`. Это означает, что исключения в главном потоке должны быть перехвачены и обработаны, чтобы потоки могли корректно завершиться. По этой причине рекомендуется не использовать `ThreadPoolExecutor` для долго выполняющихся задач.122123*initializer* – это необязательный вызываемый объект, который вызывается в начале каждого рабочего потока; *initargs* – это кортеж аргументов, передаваемых инициализатору. Если *initializer* вызовет исключение, все текущие ожидающие задачи вызовут [`BrokenThreadPool`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.thread.BrokenThreadPool), а также любая попытка отправить дополнительные задачи в пул.124125Изменено в версии 3.5: Если *max\_workers* равен `None` или не указан, он будет по умолчанию равен количеству процессоров на машине, умноженному на `5`, исходя из предположения, что `ThreadPoolExecutor` часто используется для перекрытия операций ввода-вывода, а не для загрузки ЦП, и количество рабочих должно быть больше, чем количество рабочих для [`ProcessPoolExecutor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.ProcessPoolExecutor).126127Изменено в версии 3.6: Добавлен параметр *thread\_name\_prefix*, позволяющий пользователям управлять [`threading.Thread`](https://python-all.ru/3.13/library/threading.html#threading.Thread) именами рабочих потоков, создаваемых пулом, для упрощения отладки.128129Изменено в версии 3.7: Добавлены аргументы *initializer* и *initargs*.130131Изменено в версии 3.8: Значение по умолчанию *max\_workers* изменено на `min(32, os.cpu_count() + 4)`. Это значение по умолчанию сохраняет не менее 5 рабочих для задач, связанных с вводом-выводом. Оно использует не более 32 ядер ЦП для задач, связанных с ЦП и отпускающих GIL. И оно позволяет избежать неявного использования очень больших ресурсов на многоядерных машинах.132133ThreadPoolExecutor теперь также повторно использует простаивающие рабочие потоки, прежде чем запускать *max\_workers* рабочих потоков.134135Изменено в версии 3.13: Значение по умолчанию *max\_workers* изменено на `min(32, (os.process_cpu_count() or 1) + 4)`.136137### Пример ThreadPoolExecutor138139```python140import concurrent.futures141import urllib.request142143URLS = ['http://www.foxnews.com/',144 'http://www.cnn.com/',145 'http://europe.wsj.com/',146 'http://www.bbc.co.uk/',147 'http://nonexistent-subdomain.python.org/']148149# Получить одну страницу и вывести URL и содержимое150def load_url(url, timeout):151 with urllib.request.urlopen(url, timeout=timeout) as conn:152 return conn.read()153154# Можно использовать инструкцию with, чтобы гарантировать своевременную очистку потоков155with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:156 # Запустить операции загрузки и пометить каждый future его URL157 future_to_url = {executor.submit(load_url, url, 60): url for url in URLS}158 for future in concurrent.futures.as_completed(future_to_url):159 url = future_to_url[future]160 try:161 data = future.result()162 except Exception as exc:163 print('%r generated an exception: %s' % (url, exc))164 else:165 print('%r page is %d bytes' % (url, len(data)))166```167168## ProcessPoolExecutor169170Класс [`ProcessPoolExecutor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.ProcessPoolExecutor) является подклассом [`Executor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Executor), который использует пул процессов для асинхронного выполнения вызовов. `ProcessPoolExecutor` использует модуль [`multiprocessing`](https://python-all.ru/3.13/library/multiprocessing.html#module-multiprocessing), что позволяет обойти [Глобальная блокировка интерпретатора](https://python-all.ru/3.13/glossary.html#term-global-interpreter-lock), но также означает, что только picklable-объекты могут быть выполнены и возвращены.171172Модуль `__main__` должен быть импортируемым рабочими подпроцессами. Это означает, что [`ProcessPoolExecutor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.ProcessPoolExecutor) не будет работать в интерактивном интерпретаторе.173174Вызов методов [`Executor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Executor) или [`Future`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Future) из вызываемого объекта, отправленного в [`ProcessPoolExecutor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.ProcessPoolExecutor), приведёт к взаимоблокировке.175176Обратите внимание, что ограничения на функции и аргументы, требующие возможности сериализации через pickle, в соответствии с [`multiprocessing.Process`](https://python-all.ru/3.13/library/multiprocessing.html#multiprocessing.Process) применяются при использовании [`submit()`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Executor.submit) и [`map()`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Executor.map) на [`ProcessPoolExecutor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.ProcessPoolExecutor). Не следует ожидать, что функция, определённая в интерактивном интерпретаторе (REPL), или лямбда-функция будут работать.177178#### `class concurrent.futures.ProcessPoolExecutor(max_workers=None, mp_context=None, initializer=None, initargs=(), max_tasks_per_child=None)`179180Подкласс [`Executor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Executor), который выполняет вызовы асинхронно, используя пул из не более чем *max\_workers* процессов. Если *max\_workers* равен `None` или не указан, по умолчанию будет использоваться [`os.process_cpu_count()`](https://python-all.ru/3.13/library/os.html#os.process_cpu_count). Если *max\_workers* меньше или равен `0`, то будет вызвано исключение [`ValueError`](https://python-all.ru/3.13/library/exceptions.html#ValueError). В Windows *max\_workers* должен быть меньше или равен `61`. Если это не так, то будет вызвано `ValueError`. Если *max\_workers* равен `None`, то выбранное по умолчанию значение будет не больше `61`, даже если доступно больше процессоров. *mp\_context* может быть контекстом [`multiprocessing`](https://python-all.ru/3.13/library/multiprocessing.html#module-multiprocessing) или `None`. Он будет использоваться для запуска рабочих процессов. Если *mp\_context* равен `None` или не указан, используется контекст по умолчанию `multiprocessing`. См. [Контексты и методы запуска](https://python-all.ru/3.13/library/multiprocessing.html#multiprocessing-start-methods).181182*initializer* – необязательный вызываемый объект, который вызывается при запуске каждого рабочего процесса; *initargs* – кортеж аргументов, передаваемых инициализатору. Если *initializer* вызывает исключение, все текущие ожидающие задания вызовут [`BrokenProcessPool`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.process.BrokenProcessPool), как и любая попытка отправить новые задания в пул.183184*max\_tasks\_per\_child* – необязательный аргумент, задающий максимальное количество задач, которое может выполнить один процесс, прежде чем он завершится и будет заменён новым рабочим процессом. По умолчанию *max\_tasks\_per\_child* равен `None`, что означает, что рабочие процессы будут жить столько же, сколько и пул. Если задан максимум, по умолчанию будет использоваться метод запуска "spawn" multiprocessing при отсутствии параметра *mp\_context*. Эта возможность несовместима с методом запуска "fork".185186Изменено в версии 3.3: Теперь, когда один из рабочих процессов внезапно завершается, возникает ошибка [`BrokenProcessPool`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.process.BrokenProcessPool). Ранее поведение было неопределённым, но операции с исполнителем или его future часто зависали или приводили к взаимоблокировке.187188Изменено в версии 3.7: Добавлен аргумент *mp\_context*, позволяющий пользователям управлять start\_method для рабочих процессов, создаваемых пулом.189190Добавлены аргументы *initializer* и *initargs*.191192> **Примечание**193>194> Метод запуска по умолчанию [`multiprocessing`](https://python-all.ru/3.13/library/multiprocessing.html#module-multiprocessing) (см. [Контексты и методы запуска](https://python-all.ru/3.13/library/multiprocessing.html#multiprocessing-start-methods)) изменится с *fork* в Python 3.14. Код, которому требуется *fork* для его `ProcessPoolExecutor`, должен явно указать это, передав параметр `mp_context=multiprocessing.get_context("fork")`.195196Изменено в версии 3.11: Добавлен аргумент *max\_tasks\_per\_child*, позволяющий пользователям контролировать время жизни рабочих процессов в пуле.197198Изменено в версии 3.12: В системах POSIX, если приложение имеет несколько потоков и контекст [`multiprocessing`](https://python-all.ru/3.13/library/multiprocessing.html#module-multiprocessing) использует метод запуска `"fork"`: функция [`os.fork()`](https://python-all.ru/3.13/library/os.html#os.fork), вызываемая внутри для порождения рабочих процессов, может вызвать [`DeprecationWarning`](https://python-all.ru/3.13/library/exceptions.html#DeprecationWarning). Передайте *mp\_context*, настроенный на использование другого метода запуска. См. документацию `os.fork()` для дальнейших пояснений.199200Изменено в версии 3.13: *max\_workers* по умолчанию использует [`os.process_cpu_count()`](https://python-all.ru/3.13/library/os.html#os.process_cpu_count) вместо [`os.cpu_count()`](https://python-all.ru/3.13/library/os.html#os.cpu_count).201202Изменено в версии 3.13.14 (не выпущена): Исправлена взаимоблокировка ([gh-115634](https://python-all.ru/3.13/library/concurrent.futures.html)), при которой исполнитель мог зависнуть после того, как рабочий процесс завершился, достигнув своего лимита *max\_tasks\_per\_child*, в то время как задачи оставались в очереди.203204### Пример ProcessPoolExecutor205206```python207import concurrent.futures208import math209210PRIMES = [211 112272535095293,212 112582705942171,213 112272535095293,214 115280095190773,215 115797848077099,216 1099726899285419]217218def is_prime(n):219 if n < 2:220 return False221 if n == 2:222 return True223 if n % 2 == 0:224 return False225226 sqrt_n = int(math.floor(math.sqrt(n)))227 for i in range(3, sqrt_n + 1, 2):228 if n % i == 0:229 return False230 return True231232def main():233 with concurrent.futures.ProcessPoolExecutor() as executor:234 for number, prime in zip(PRIMES, executor.map(is_prime, PRIMES)):235 print('%d is prime: %s' % (number, prime))236237if __name__ == '__main__':238 main()239```240241## Объекты Future242243Класс [`Future`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Future) инкапсулирует асинхронное выполнение вызываемого объекта. Экземпляры `Future` создаются с помощью [`Executor.submit()`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Executor.submit).244245#### `class concurrent.futures.Future`246247Инкапсулирует асинхронное выполнение вызываемого объекта. Экземпляры `Future` создаются с помощью [`Executor.submit()`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Executor.submit) и не должны создаваться напрямую, за исключением тестирования.248249#### `cancel()`250251Пытается отменить вызов. Если вызов в данный момент выполняется или уже завершён и не может быть отменён, метод вернёт `False`, в противном случае вызов будет отменён и метод вернёт `True`.252253#### `cancelled()`254255Возвращает `True`, если вызов был успешно отменён.256257#### `running()`258259Возвращает `True`, если вызов в данный момент выполняется и не может быть отменён.260261#### `done()`262263Возвращает `True`, если вызов был успешно отменён или завершён.264265#### `result(timeout=None)`266267Возвращает значение, возвращённое вызовом. Если вызов ещё не завершился, этот метод будет ждать до *timeout* секунд. Если вызов не завершится за *timeout* секунд, будет вызвано [`TimeoutError`](https://python-all.ru/3.13/library/exceptions.html#TimeoutError). *timeout* может быть целым числом или числом с плавающей запятой. Если *timeout* не указан или равен `None`, время ожидания не ограничено.268269Если future отменён до завершения, будет вызвано [`CancelledError`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.CancelledError).270271Если вызов вызвал исключение, этот метод вызовет то же самое исключение.272273#### `exception(timeout=None)`274275Возвращает исключение, вызванное вызовом. Если вызов ещё не завершён, этот метод будет ожидать до *timeout* секунд. Если вызов не завершится за *timeout* секунд, будет вызвано [`TimeoutError`](https://python-all.ru/3.13/library/exceptions.html#TimeoutError). *timeout* может быть целым числом или числом с плавающей запятой. Если *timeout* не указан или `None`, время ожидания не ограничено.276277Если future отменён до завершения, будет вызвано [`CancelledError`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.CancelledError).278279Если вызов завершился без исключения, возвращается `None`.280281#### `add_done_callback(fn)`282283Прикрепляет вызываемый объект *fn* к future. *fn* будет вызван с future в качестве единственного аргумента, когда future отменён или завершит выполнение.284285Добавленные вызываемые объекты вызываются в порядке их добавления и всегда вызываются в потоке, принадлежащем процессу, который их добавил. Если вызываемый объект вызывает подкласс [`Exception`](https://python-all.ru/3.13/library/exceptions.html#Exception), это будет зарегистрировано и проигнорировано. Если вызываемый объект вызывает подкласс [`BaseException`](https://python-all.ru/3.13/library/exceptions.html#BaseException), поведение не определено.286287Если future уже завершён или отменён, *fn* будет вызван немедленно.288289Следующие методы `Future` предназначены для использования в модульных тестах и реализациях [`Executor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Executor).290291#### `set_running_or_notify_cancel()`292293Этот метод должен вызываться только реализациями [`Executor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Executor) перед выполнением работы, связанной с `Future`, и модульными тестами.294295Если метод возвращает `False`, то `Future` был отменён, то есть [`Future.cancel()`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Future.cancel) был вызван и вернул `True`. Все потоки, ожидающие завершения `Future` (например, через [`as_completed()`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.as_completed) или [`wait()`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.wait)), будут разбужены.296297Если метод возвращает `True`, то `Future` не был отменён и переведён в состояние выполнения, то есть вызовы [`Future.running()`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Future.running) будут возвращать `True`.298299Этот метод можно вызвать только один раз, и его нельзя вызывать после вызова [`Future.set_result()`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Future.set_result) или [`Future.set_exception()`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Future.set_exception).300301#### `set_result(result)`302303Устанавливает результат работы, связанной с `Future`, в *result*.304305Этот метод должен использоваться только реализациями [`Executor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Executor) и модульными тестами.306307Изменено в версии 3.8: Этот метод вызывает [`concurrent.futures.InvalidStateError`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.InvalidStateError), если `Future` уже завершён.308309#### `set_exception(exception)`310311Устанавливает результат работы, связанной с `Future`, в [`Exception`](https://python-all.ru/3.13/library/exceptions.html#Exception) *исключение*.312313Этот метод должен использоваться только реализациями [`Executor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Executor) и модульными тестами.314315Изменено в версии 3.8: Этот метод вызывает [`concurrent.futures.InvalidStateError`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.InvalidStateError), если `Future` уже завершён.316317## Функции модуля318319#### `concurrent.futures.wait(fs, timeout=None, return_when=ALL_COMPLETED)`320321Ожидает завершения экземпляров [`Future`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Future) (возможно, созданных разными экземплярами [`Executor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Executor)), заданных в *fs*. Дублирующиеся future, переданные в *fs*, удаляются и возвращаются только один раз. Возвращает именованный кортеж из двух множеств. Первое множество, названное `done`, содержит future, которые завершились (завершённые или отменённые future) до завершения ожидания. Второе множество, названное `not_done`, содержит future, которые не завершились (ожидающие или выполняющиеся future).322323*timeout* можно использовать для управления максимальным количеством секунд ожидания перед возвратом. *timeout* может быть целым числом или числом с плавающей запятой. Если *timeout* не указан или `None`, время ожидания не ограничено.324325*return\_when* указывает, когда эта функция должна вернуть результат. Он должен быть одной из следующих констант:326327| Константа | Описание |328| --- | --- |329| concurrent.futures.FIRST\_COMPLETED | Функция возвращает результат, когда любой future завершается или отменяется. |330| concurrent.futures.FIRST\_EXCEPTION | Функция вернёт результат, когда любой future завершится, возбудив исключение. Если ни один future не возбудит исключение, то это эквивалентно [`ALL_COMPLETED`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.ALL_COMPLETED). |331| concurrent.futures.ALL\_COMPLETED | Функция вернёт результат, когда все futures завершатся или будут отменены. |332333#### `concurrent.futures.as_completed(fs, timeout=None)`334335Возвращает итератор по экземплярам [`Future`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Future) (возможно, созданным разными экземплярами [`Executor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.Executor)), заданным в *fs*, который выдаёт future по мере их завершения (завершённые или отменённые future). Любые future, переданные в *fs*, которые дублируются, будут возвращены один раз. Все future, завершившиеся до вызова `as_completed()`, будут выданы первыми. Возвращаемый итератор вызывает [`TimeoutError`](https://python-all.ru/3.13/library/exceptions.html#TimeoutError), если [`__next__()`](https://python-all.ru/3.13/library/stdtypes.html#iterator.__next__) вызывается, а результат недоступен через *timeout* секунд после исходного вызова `as_completed()`. *timeout* может быть целым числом или числом с плавающей запятой. Если *timeout* не указан или `None`, время ожидания не ограничено.336337> **См. также**338>339> **[**PEP 3148**](https://python-all.ru/3.13/library/concurrent.futures.html) – futures - execute computations asynchronously**340>341> Предложение, которое описывало эту возможность для включения в стандартную библиотеку Python.342343## Классы исключений344345#### `exception concurrent.futures.CancelledError`346347Возникает при отмене future.348349#### `exception concurrent.futures.TimeoutError`350351Устаревший псевдоним `TimeoutError`, возникает, когда операция с future превышает заданный таймаут.352353Изменено в версии 3.11: Этот класс стал псевдонимом для `TimeoutError`.354355#### `exception concurrent.futures.BrokenExecutor`356357Производный от [`RuntimeError`](https://python-all.ru/3.13/library/exceptions.html#RuntimeError), этот класс исключения возникает, когда исполнитель по какой-то причине сломан и не может использоваться для отправки или выполнения новых задач.358359Добавлено в версии 3.7.360361#### `exception concurrent.futures.InvalidStateError`362363Возникает, когда над future выполняется операция, которая не разрешена в текущем состоянии.364365Добавлено в версии 3.8.366367#### `exception concurrent.futures.thread.BrokenThreadPool`368369Производный от [`BrokenExecutor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.BrokenExecutor), этот класс исключения возникает, когда один из рабочих потоков [`ThreadPoolExecutor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor) не смог инициализироваться.370371Добавлено в версии 3.7.372373#### `exception concurrent.futures.process.BrokenProcessPool`374375Производный от [`BrokenExecutor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.BrokenExecutor) (ранее [`RuntimeError`](https://python-all.ru/3.13/library/exceptions.html#RuntimeError)), этот класс исключения возникает, когда один из рабочих процессов [`ProcessPoolExecutor`](https://python-all.ru/3.13/library/concurrent.futures.html#concurrent.futures.ProcessPoolExecutor) завершился нечисто (например, если он был убит извне).376377Добавлено в версии 3.3.378