У вас есть несколько разных опций, в зависимости от того, какой основной цикл имеет ваша существующая программа.
Если это mainloop из библиотеки GUI, Возможно, Twisted уже имеет поддержку . В этом случае вы можете просто использовать его.
Вы также можете написать свой собственный реактор. Для этого не так много отличной документации, но вы можете посмотреть, как qtreactor реализует внешний плагин реактора для Twisted.
Вы также можете написать минимальный реактор, используя threadedselectreactor
. Документация для этого также скудна, но реактор wxpython реализован с его использованием. Лично я бы не рекомендовал этот подход, так как его сложно протестировать, и он может привести к запутанным условиям гонки, но у него есть то преимущество, что он позволяет вам использовать почти весь сетевой код Twisted по умолчанию только с тонким слоем обертывания.
Если вы действительно уверены, что не хотите, чтобы ваш doComputation
был асинхронным, и вы хотите, чтобы ваша программа блокировалась в ожидании ответа Twisted, выполните следующие действия:
- запустите Twisted в другом потоке до запуска основного цикла, например
twistedThread = Thread(target=reactor.run); twistedThread.start()
- создает экземпляр объекта для связи RPC (скажем,
RPCDoer
) в потоке вашего основного цикла, чтобы у вас была ссылка на него. Удостоверьтесь, что фактически включили его Twisted логику с помощью reactor.callFromThread
, чтобы вам не нужно было оборачивать все его вызовы Twisted API.
- Реализация
RPCDoer.doRPC
для возврата Отложено , используя только вызовы Twisted API (т.е. не вызывайте в существующий код приложения, поэтому вам не нужно беспокоиться о безопасности потоков для объектов вашего приложения ; передать doRPC
всю необходимую информацию в качестве аргументов).
Теперь вы можете реализовать doComputation
так:
def doComputation(self):
rpcResult = blockingCallFromThread(reactor, self.myRPCDoer.doRPC)
return self.computeSomethingFrom(rpcResult)
- Не забудьте вызвать
reactor.callFromThread(reactor.stop); twistedThread.join()
из процедуры отключения вашего основного цикла, в противном случае вы можете увидеть некоторые запутанные трассировки или сообщения журнала при выходе.
Наконец, один вариант, который вы должны рассмотреть, особенно в долгосрочной перспективе: сбросить существующий основной цикл и найти способ просто использовать Twisted. По моему опыту, это правильный ответ для 9 из 10 участников таких вопросов. Я не говорю, что это всегда путь - есть много случаев, когда вам действительно нужно сохранить свой основной цикл, или когда просто слишком много усилий, чтобы избавиться от существующего петля. Но поддержание вашего собственного цикла - тоже работа. Имейте в виду, что витая петля была тщательно протестирована миллионами пользователей и использовалась в самых разных средах. Если ваш цикл также очень зрелый, это может не иметь большого значения, но если вы пишете небольшую новую программу, разница в надежности может быть значительной.