Документация Python неофициальный перевод

concurrent.interpreters.md

264 строк · 22.7 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.14/library/concurrent.interpreters.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `concurrent.interpreters` – Несколько интерпретаторов в одном процессе89Добавлено в версии 3.14.1011**Исходный код:** [Lib/concurrent/interpreters](https://python-all.ru/3.14/library/concurrent.interpreters.html)1213---1415Модуль `concurrent.interpreters` строит интерфейсы более высокого уровня поверх низкоуровневого модуля `_interpreters`.1617Модуль в первую очередь предназначен для предоставления базового API для управления интерпретаторами (также называемыми «субинтерпретаторами») и выполнения в них кода. Выполнение в основном включает переключение на интерпретатор (в текущем потоке) и вызов функции в этом контексте выполнения.1819Что касается параллелизма, сами интерпретаторы (и этот модуль) не предоставляют ничего, кроме изоляции, которая сама по себе не полезна. Реальная параллельность доступна отдельно через [`threads`](https://python-all.ru/3.14/library/threading.html#module-threading). См. [ниже](https://python-all.ru/3.14/library/concurrent.interpreters.html#interp-concurrency)2021> **См. также**22>23> **[`InterpreterPoolExecutor`](https://python-all.ru/3.14/library/concurrent.futures.html#concurrent.futures.InterpreterPoolExecutor)**24>25> Объединяет потоки с интерпретаторами в знакомом интерфейсе.26>27> **[Изоляция модулей расширений](https://python-all.ru/3.14/howto/isolating-extensions.html#isolating-extensions-howto)**28>29> Как обновить модуль расширения для поддержки нескольких интерпретаторов.30>31> [**PEP 554**](https://python-all.ru/3.14/library/concurrent.interpreters.html)32>33> [**PEP 734**](https://python-all.ru/3.14/library/concurrent.interpreters.html)34>35> [**PEP 684**](https://python-all.ru/3.14/library/concurrent.interpreters.html)3637[Доступность](https://python-all.ru/3.14/library/intro.html#availability): не WASI.3839Этот модуль не работает или недоступен на WebAssembly. Подробнее см. [платформы WebAssembly](https://python-all.ru/3.14/library/intro.html#wasm-availability).4041## Ключевые детали4243Прежде чем углубляться, стоит помнить о нескольких деталях, касающихся использования нескольких интерпретаторов:4445- [изолированы](https://python-all.ru/3.14/library/concurrent.interpreters.html#interp-isolation), по умолчанию46- нет неявных потоков47- не все пакеты PyPI пока поддерживают использование в нескольких интерпретаторах4849## Введение5051«Интерпретатор» – это, по сути, контекст выполнения среды выполнения Python. Он содержит всё состояние, необходимое среде выполнения для выполнения программы. Сюда входят такие вещи, как состояние импорта и встроенные функции. (Каждый поток, даже если есть только главный поток, имеет некоторое дополнительное состояние среды выполнения, помимо текущего интерпретатора, связанное с текущим исключением и циклом вычисления байт-кода.)5253Концепция и функциональность интерпретатора были частью Python начиная с версии 2.2, но эта возможность была доступна только через C-API и не была широко известна, а [изоляция](https://python-all.ru/3.14/library/concurrent.interpreters.html#interp-isolation) была относительно неполной до версии 3.12.5455### Несколько интерпретаторов и изоляция5657Реализация Python может поддерживать использование нескольких интерпретаторов в одном процессе. CPython поддерживает это. Каждый интерпретатор эффективно изолирован от других (за небольшим числом тщательно контролируемых исключений, глобальных для процесса).5859Эта изоляция в первую очередь полезна как строгое разделение между различными логическими компонентами программы, где требуется тщательный контроль над тем, как эти компоненты взаимодействуют.6061> **Примечание**62>63> Интерпретаторы в одном процессе технически никогда не могут быть строго изолированы друг от друга, поскольку в пределах одного процесса существует мало ограничений на доступ к памяти. Среда выполнения Python прилагает все усилия для изоляции, но модули расширения могут легко нарушить её. Поэтому не используйте несколько интерпретаторов в ситуациях, критичных с точки зрения безопасности, где они не должны иметь доступа к данным друг друга.6465### Выполнение в интерпретаторе6667Выполнение в другом интерпретаторе включает переключение на него в текущем потоке и последующий вызов некоторой функции. Среда выполнения будет выполнять функцию, используя состояние текущего интерпретатора. Модуль `concurrent.interpreters` предоставляет базовый API для создания и управления интерпретаторами, а также для операции переключения и вызова.6869Никакие другие потоки не запускаются автоматически для этой операции. Однако для этого существует [вспомогательная функция](https://python-all.ru/3.14/library/concurrent.interpreters.html#interp-call-in-thread). Существует ещё одна специальная вспомогательная функция для вызова встроенной функции [`exec()`](https://python-all.ru/3.14/library/functions.html#exec) в интерпретаторе.7071Когда [`exec()`](https://python-all.ru/3.14/library/functions.html#exec) (или [`eval()`](https://python-all.ru/3.14/library/functions.html#eval)) вызываются в интерпретаторе, они выполняются с использованием модуля `__main__` интерпретатора в качестве пространства имён «globals». То же самое верно для функций, не связанных ни с одним модулем. Это аналогично тому, как сценарии, запускаемые из командной строки, выполняются в модуле `__main__`.7273### Конкурентность и параллелизм7475Как отмечалось ранее, интерпретаторы сами по себе не обеспечивают никакой конкурентности. Они строго представляют изолированный контекст выполнения, который среда выполнения будет использовать *в текущем потоке*. Эта изоляция делает их похожими на процессы, но они по-прежнему обладают эффективностью внутри процесса, как потоки.7677Тем не менее, интерпретаторы естественным образом поддерживают определённые виды конкурентности. У этой изоляции есть мощный побочный эффект. Она позволяет использовать другой подход к конкурентности, отличный от асинхронного программирования или потоков. Это модель конкурентности, похожая на CSP или модель акторов, модель, о которой относительно легко рассуждать.7879Эту модель конкурентности можно использовать в одном потоке, переключаясь между интерпретаторами в стиле Stackless. Однако эта модель более полезна, когда интерпретаторы комбинируются с несколькими потоками. В основном это включает запуск нового потока, в котором переключаются на другой интерпретатор и выполняют там нужный код.8081Каждый реальный поток в Python, даже если вы работаете только в главном потоке, имеет свой собственный *текущий* контекст выполнения. Несколько потоков могут использовать один и тот же интерпретатор или разные.8283На высоком уровне можно рассматривать комбинацию потоков и интерпретаторов как потоки с возможностью совместного использования по желанию.8485В качестве важного дополнительного преимущества интерпретаторы достаточно изолированы, чтобы не разделять [GIL](https://python-all.ru/3.14/glossary.html#term-GIL), а это означает, что сочетание потоков с несколькими интерпретаторами обеспечивает полноценный многоядерный параллелизм. (Так обстоит дело начиная с Python 3.12.)8687### Взаимодействие между интерпретаторами8889На практике несколько интерпретаторов полезны только в том случае, если есть способ взаимодействия между ними. Обычно это подразумевает ту или иную форму передачи сообщений, но может означать и тщательно контролируемое совместное использование данных.9091С учетом этого модуль `concurrent.interpreters` предоставляет реализацию [`queue.Queue`](https://python-all.ru/3.14/library/queue.html#queue.Queue), доступную через [`create_queue()`](https://python-all.ru/3.14/library/concurrent.interpreters.html#concurrent.interpreters.create_queue).9293### «Совместное использование» объектов9495Любые данные, фактически разделяемые между интерпретаторами, теряют потокобезопасность, обеспечиваемую [GIL](https://python-all.ru/3.14/glossary.html#term-GIL). В расширениях для решения этой проблемы есть различные варианты. Однако из кода на Python отсутствие потокобезопасности означает, что объекты, за несколькими исключениями, не могут быть фактически общими. Вместо этого приходится создавать копию, что означает, что изменяемые объекты не будут синхронизированы.9697По умолчанию большинство объектов копируются с помощью [`pickle`](https://python-all.ru/3.14/library/pickle.html#module-pickle) при передаче другому интерпретатору. Почти все неизменяемые встроенные объекты либо напрямую разделяются, либо копируются эффективно. Например:9899- [`None`](https://python-all.ru/3.14/library/constants.html#None)100- [`bool`](https://python-all.ru/3.14/library/functions.html#bool) ([`True`](https://python-all.ru/3.14/library/constants.html#True) и [`False`](https://python-all.ru/3.14/library/constants.html#False))101- [`bytes`](https://python-all.ru/3.14/library/stdtypes.html#bytes)102- [`str`](https://python-all.ru/3.14/library/stdtypes.html#str)103- [`int`](https://python-all.ru/3.14/library/functions.html#int)104- [`float`](https://python-all.ru/3.14/library/functions.html#float)105- [`tuple`](https://python-all.ru/3.14/library/stdtypes.html#tuple) (и другие подобные поддерживаемые объекты)106107Существует небольшое количество типов Python, на самом деле разделяющих изменяемые данные между интерпретаторами:108109- [`memoryview`](https://python-all.ru/3.14/library/stdtypes.html#memoryview)110- [`Queue`](https://python-all.ru/3.14/library/concurrent.interpreters.html#concurrent.interpreters.Queue)111112## Ссылка113114Этот модуль определяет следующие функции:115116#### `concurrent.interpreters.list_all()`117118Возвращает [`list`](https://python-all.ru/3.14/library/stdtypes.html#list) объектов [`Interpreter`](https://python-all.ru/3.14/library/concurrent.interpreters.html#concurrent.interpreters.Interpreter), по одному для каждого существующего интерпретатора.119120#### `concurrent.interpreters.get_current()`121122Возвращает объект [`Interpreter`](https://python-all.ru/3.14/library/concurrent.interpreters.html#concurrent.interpreters.Interpreter) для текущего выполняющегося интерпретатора.123124#### `concurrent.interpreters.get_main()`125126Возвращает объект [`Interpreter`](https://python-all.ru/3.14/library/concurrent.interpreters.html#concurrent.interpreters.Interpreter) для главного интерпретатора. Это интерпретатор, созданный средой выполнения для запуска [REPL](https://python-all.ru/3.14/glossary.html#term-REPL) или скрипта, указанного в командной строке. Обычно он единственный.127128#### `concurrent.interpreters.create()`129130Инициализирует новый (бездействующий) интерпретатор Python и возвращает для него объект [`Interpreter`](https://python-all.ru/3.14/library/concurrent.interpreters.html#concurrent.interpreters.Interpreter).131132#### `concurrent.interpreters.create_queue()`133134Инициализирует новую очередь между интерпретаторами и возвращает для нее объект [`Queue`](https://python-all.ru/3.14/library/concurrent.interpreters.html#concurrent.interpreters.Queue).135136### Объекты Interpreter137138#### `class concurrent.interpreters.Interpreter(id)`139140Один интерпретатор в текущем процессе.141142Обычно `Interpreter` не следует вызывать напрямую. Вместо этого используйте [`create()`](https://python-all.ru/3.14/library/concurrent.interpreters.html#concurrent.interpreters.create) или одну из других функций модуля.143144#### `id`145146(только для чтения)147148Идентификатор соответствующего интерпретатора.149150#### `whence`151152(только для чтения)153154Строка, описывающая происхождение интерпретатора.155156#### `is_running()`157158Возвращает `True`, если интерпретатор в данный момент выполняет код в своём модуле `__main__`, и `False` в противном случае.159160#### `close()`161162Финализировать и уничтожить интерпретатор.163164#### `prepare_main(ns=None, **kwargs)`165166Привязывает объекты в модуле `__main__` интерпретатора.167168Некоторые объекты действительно являются общими, а некоторые копируются эффективно, но большинство копируется через [`pickle`](https://python-all.ru/3.14/library/pickle.html#module-pickle). См. [«Совместное использование» объектов](https://python-all.ru/3.14/library/concurrent.interpreters.html#interp-object-sharing).169170#### `exec(code, /, dedent=True)`171172Выполнить данный исходный код в интерпретаторе (в текущем потоке).173174#### `call(callable, /, *args, **kwargs)`175176Возвращает результат вызова данной функции в интерпретаторе (в текущем потоке).177178#### `call_in_thread(callable, /, *args, **kwargs)`179180Выполнить данную функцию в интерпретаторе (в новом потоке).181182### Исключения183184#### `exception concurrent.interpreters.InterpreterError`185186Это исключение, подкласс [`Exception`](https://python-all.ru/3.14/library/exceptions.html#Exception), вызывается при возникновении ошибки, связанной с интерпретатором.187188#### `exception concurrent.interpreters.InterpreterNotFoundError`189190Это исключение, подкласс [`InterpreterError`](https://python-all.ru/3.14/library/concurrent.interpreters.html#concurrent.interpreters.InterpreterError), вызывается, когда целевой интерпретатор больше не существует.191192#### `exception concurrent.interpreters.ExecutionFailed`193194Это исключение, подкласс [`InterpreterError`](https://python-all.ru/3.14/library/concurrent.interpreters.html#concurrent.interpreters.InterpreterError), вызывается, когда выполняемый код породил необработанное исключение.195196#### `excinfo`197198Базовый снимок исключения, возникшего в другом интерпретаторе.199200#### `exception concurrent.interpreters.NotShareableError`201202Это исключение, подкласс [`TypeError`](https://python-all.ru/3.14/library/exceptions.html#TypeError), вызывается, когда объект невозможно отправить другому интерпретатору.203204### Взаимодействие между интерпретаторами205206#### `class concurrent.interpreters.Queue(id)`207208Обёртка вокруг низкоуровневой очереди, работающей между интерпретаторами, которая реализует интерфейс [`queue.Queue`](https://python-all.ru/3.14/library/queue.html#queue.Queue). Базовая очередь может быть создана только через [`create_queue()`](https://python-all.ru/3.14/library/concurrent.interpreters.html#concurrent.interpreters.create_queue).209210Некоторые объекты действительно являются общими, а некоторые копируются эффективно, но большинство копируется через [`pickle`](https://python-all.ru/3.14/library/pickle.html#module-pickle). См. [«Совместное использование» объектов](https://python-all.ru/3.14/library/concurrent.interpreters.html#interp-object-sharing).211212#### `id`213214(только для чтения)215216Идентификатор очереди.217218#### `exception concurrent.interpreters.QueueEmptyError`219220Это исключение, подкласс [`queue.Empty`](https://python-all.ru/3.14/library/queue.html#queue.Empty), вызывается из `Queue.get()` и `Queue.get_nowait()`, когда очередь пуста.221222#### `exception concurrent.interpreters.QueueFullError`223224Это исключение, подкласс [`queue.Full`](https://python-all.ru/3.14/library/queue.html#queue.Full), возбуждается из `Queue.put()` и `Queue.put_nowait()`, когда очередь полна.225226## Базовое использование227228Создание интерпретатора и выполнение в нём кода:229230```python231from concurrent import interpreters232233interp = interpreters.create()234235# Выполнить в текущем потоке ОС.236237interp.exec('print("spam!")')238239interp.exec("""if True:240    print('spam!')241    """)242243from textwrap import dedent244interp.exec(dedent("""245    print('spam!')246    """))247248def run(arg):249    return arg250251res = interp.call(run, 'spam!')252print(res)253254def run():255    print('spam!')256257interp.call(run)258259# Выполнить в новом потоке ОС.260261t = interp.call_in_thread(run)262t.join()263```264