Да, имеет смысл использовать (реальные) потоки или процессы из gevent
для кода, который должен быть асинхронным, но не может быть обезличен gevent
.
Конечно, может быть сложно получить правильные результаты - во-первых, потому что вы, возможно, запатентовали threading
, а во-вторых, потому что вы хотите, чтобы ваши кооперативные потоки могли блокировать пул или результат пула, не блокируя весь основной нить.
Но это именно то, для чего gevent.threadpool
.
Если бы вы использовали concurrent.futures.ThreadPoolExecutor
в приложении, отличном от gevent
, monkeypatch threading
, а затем используйте gevent.threadpool.ThreadPoolExecutor
.
Если бы вы использовали multiprocessing.dummy.Pool
в приложении, отличном от gevent
, monkeypatch threading
, а затем используйте gevent.threadpool.ThreadPool
.
В любом случае, такие методы, как map
, submit
, apply_async
и т. Д., Работают почти так, как вы ожидаете. Объекты Future
и AsyncResult
хорошо играют с гринлетами; Вы можете gevent.wait
вещей, или прикрепить обратные вызовы (которые будут работать как гринлеты) и т. д. В большинстве случаев это просто работает как магия, а в остальное время это не слишком сложно выяснить.
Использование процессов вместо потоков выполнимо, но не так хорошо. AFAIK, нет обёрток для чего-то такого полного, как multiprocessing.Process
или multiprocessing.Pool
, и попытка использовать обычный multiprocessing
просто зависает. Вы можете вручную fork
, если вы не работаете в Windows, но это все, что встроено. Если вам действительно нужна многопроцессорная обработка, вам может потребоваться выполнить многослойную работу, когда ваши гринлеты не будут работать. не разговаривать с процессом, а вместо этого общаться с потоком, который создает канал, вилки, execs, а затем прокси между миром gevent и дочерним процессом.
Если вызовы занимают много времени, потому что они ожидают ввода-вывода от бэкэнд-службы, или ожидают на подпроцессе, или выполняют неповоротливую работу по GIL-выпуску, я бы не стал пытаться делать multiprocessing
, Но если они отнимают много времени из-за того, что загружают процессор… ну, тогда вам нужно либо заставить многопроцессорную работу работать, либо перейти на более низкий уровень и просто выделить subprocess.Popen([sys.executable, 'workerscript.py'])
.