使用gevent猴子补丁与线程使线程串行工作
我正在使用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 个回答
0
如果你把代码中的 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):
...
这样的话,它就会按照你的想法正常工作了。
33
当在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'