Ответ 1
Нормальный импорт является потокобезопасным, поскольку они приобретают блокировку импорта до выполнения и освобождают его после импорта. Если вы добавите свой собственный импорт, используя доступные крючки, обязательно добавьте к нему эту схему блокировки. Доступ к функциям блокировки в Python можно получить с помощью модуля imp
(imp.lock_held()
/acquire_lock()
/release_lock()
).
Использование этой блокировки импорта не создаст никаких взаимных ошибок или ошибок зависимостей, кроме круговых зависимостей уже известных.
Низкоуровневый вызов для создания потока clone
в Linux, потоки в Python - это операция, подобная fork. Викинг и клонирование применяют различные типы поведения на различных сегментах памяти. Например, только потоки не разделяются потоками, по сравнению с вилками, которые клонируют больше сегментов (данные (часто COW), стек, код, куча), эффективно не разделяя его содержимое. Механизм импорта в Python использует глобальное пространство имен, которое не помещается в стек, используя совместно используемый сегмент с его потоками. Поскольку побочные эффекты (т.е. Изменения в памяти) импорта работают в одних и тех же сегментах, он работает как однопоточная программа. Однако будьте осторожны, чтобы использовать поточнобезопасные библиотеки в вашем импорте для многопоточных программ. Он будет заставлять хаос использовать вызовы функций, которые не являются потокобезопасными в такой среде.
Кстати, потоковые программы на Python страдают GIL, которые не позволят значительно повысить производительность, если ваша программа не связана с I/O или полагаться на C или внешние потокобезопасные библиотеки (поскольку они освобождают GIL перед выполнением). Запуск из двух потоков одна и та же импортированная функция не будет выполняться одновременно из-за этого GIL. Обратите внимание, что это только ограничение CPython, и другие реализации Python будут иметь другое поведение.
Чтобы ответить на ваше редактирование: импортированные модули все кэшируются Python. Если модуль уже загружен в кеш, он не будет запущен снова, и оператор (или функция) импорта сразу вернется. Вам не нужно реализовывать поиск кэша в sys.modules, Python делает это для вас и не будет imp
блокировать что-либо, кроме GIL для поиска sys.modules.
Чтобы ответить на второе редактирование: я предпочитаю поддерживать более простой код, чем пытаться оптимизировать вызовы для библиотек, которые я использую (в данном случае, стандартная библиотека). Обоснование заключается в том, что время, требуемое для выполнения чего-либо, обычно намного важнее времени, необходимого для импорта модуля, который это делает. Кроме того, время, необходимое для поддержания такого кода во всем проекте, намного превышает время, необходимое для его выполнения. Все это сводится к: "время программиста более ценно, чем время процессора".