Использование gevent monkey patching с нарезанием резьбы заставляет резьбу работать последовательно
Я использую gevent и я-обезьяна, исправляющая все.
Похоже, что обезьянья заплатка заставляет резьбу работать последовательно.
Мой код:
import threading
from gevent import monkey; monkey.patch_all()
class ExampleThread(threading.Thread):
def run(self):
do_stuff() # takes a few minutes to finish
print 'finished working'
if __name__ == '__main__':
worker = ExampleThread()
worker.start()
print 'this should be printed before the worker finished'
Таким образом, поток работает не так, как ожидалось.
Но если я удаляю monkey.patch_all()
, он работает нормально.
Проблема в том, что мне нужен monkey.patch_all()
для использования gevent (теперь показано в коде выше)
Мое решение:
Я изменил
monkey.patch_all()
К
monkey.patch_all(thread=False)
Так что я не латаю нитка.
2 ответа:
, когда потоки патченные в gevent, они ведут себя как сопрограммы. Это означает, что вы должны явно уступить управление, чтобы сделать возможным выполнение других сопрограмм.
Способ сделать это-вызвать блокирующую операцию, которая была исправлена (это даст автоматически) или
gevent.sleep
:#!/usr/bin/env python from gevent import monkey, sleep monkey.patch_all() import threading class ExampleThread(threading.Thread): def run(self): for i in xrange(10): print 'working' sleep() if __name__ == '__main__': worker = ExampleThread() worker.start() print 'this will be printed after the first call to sleep'
Вы можете оставить свой потоковый класс на месте, если вы замените
Thread
наGreenlet
, например так:from gevent import monkey from gevent import Greenlet from threading import Thread class ThreadLikeGreenlet(Greenlet): def __init__(self, name=None, target=None, args=(), kwargs=()): super().__init__(target, *args, **dict(kwargs)) self.name = name def is_gevent_patched(): return monkey.is_module_patched('threading') if is_gevent_patched(): Thread = ThreadLikeGreenlet # substitute Thread with Greenlet class ExampleThread(Thread): ...
Тогда он будет работать так, как вы хотите.