Ответ 1
Я думаю, что ваше нынешнее понимание в основном правильное. Twisted - это просто библиотека Python, и написанный вами код Python, который вы пишете для его использования, выполняется нормально, как вы ожидаете, код Python: если у вас есть только один поток (и один процесс), тогда происходит только одна вещь. Почти ни один API, предоставляемый Twisted, не создает новые потоки или процессы, поэтому в нормальном ходу вещей ваш код работает последовательно; isPrime
не может выполнить второй раз, пока он не завершит выполнение в первый раз.
По-прежнему рассматривая только один поток (и один процесс), все "concurrency" или "parallelism" Twisted происходят из-за того, что вместо блокировки сетевого ввода-вывода (и некоторых других блокировок операций), Twisted предоставляет инструменты для выполнения операции неблокирующим способом. Это позволяет вашей программе продолжать выполнять другую работу, если она в противном случае могла бы застрять, ничего не делая, ожидая завершения операции блокировки ввода-вывода (например, чтения или записи в сокет).
Можно сделать вещи "асинхронными", разделив их на маленькие куски и разрешив обработчикам событий между этими кусками. Иногда это полезный подход, если преобразование не делает код слишком сложным для понимания и поддержки. Twisted предоставляет помощника для планирования этих кусков работы, cooperate
. Полезно использовать этот помощник, поскольку он может принимать решения о планировании на основе всех разных источников работы и гарантировать, что есть время, оставшееся для обслуживания источников событий без значительных дополнительных латентностей (другими словами, чем больше заданий вы добавляете к нему, тем меньше времени будет у каждой работы, так что реактор может продолжать выполнять свою работу).
Twisted также предоставляет несколько API для обработки потоков и процессов. Они могут быть полезны, если не очевидно, как разбить работу на куски. Вы можете использовать deferToThread
для запуска (потокобезопасной!) Функции в пуле потоков. Удобно, что этот API возвращает Deferred
, который, в конце концов, запускает возвращаемое значение функции (или с помощью Failure
, если функция вызывает исключение). Эти Отсрочки выглядят как любой другой, и что касается использующего их кода, он может так же возвращаться от вызова, как getPage
- функция, которая не использует никаких дополнительных потоков, просто неблокирующих операций ввода-вывода и обработчиков событий.
Поскольку Python не идеально подходит для запуска нескольких потоков, связанных с процессором, в одном процессе, Twisted также предоставляет неблокирующий API для запуска и передачи сообщений с дочерними процессами. Вы можете отключить вычисления для таких процессов, чтобы использовать преимущества дополнительных процессоров или ядер, не беспокоясь о том, что GIL замедляет вас, что не предлагает ни стратегия разделения, ни поток. API-интерфейс самого низкого уровня для работы с такими процессами - reactor.spawnProcess
. Существует также Ampoule, пакет, который будет управлять пулом процессов для вас и предоставляет аналог deferToThread
для процессов, deferToAMPProcess
.