While double checking that the threading.Condition correctly fixed by a monkey, I noticed that the monkey carried by threading.Thread(β¦).start() behaves differently than gevent.spawn(β¦) .
Consider:
from gevent import monkey; monkey.patch_all() from threading import Thread, Condition import gevent cv = Condition() def wait_on_cv(x): cv.acquire() cv.wait() print "Here:", x cv.release() # XXX: This code yields "This operation would block forever" when joining the first thread threads = [ gevent.spawn(wait_on_cv, x) for x in range(10) ] """ # XXX: This code, which seems semantically similar, works correctly threads = [ Thread(target=wait_on_cv, args=(x, )) for x in range(10) ] for t in threads: t.start() """ cv.acquire() cv.notify_all() print "Notified!" cv.release() for x, thread in enumerate(threads): print "Joining", x thread.join()
Please note that two comments starting with XXX .
When using the first line (with gevent.spawn ), the first thread.join() throws an exception:
Notified!
Joining 0
Traceback (most recent call last):
File "foo.py", line 30, in
thread.join ()
File "... / gevent / greenlet.py", line 291, in join
result = self.parent.switch ()
File "... / gevent / hub.py", line 381, in switch
return greenlet.switch (self)
gevent.hub.LoopExit: This operation would block forever
However, Thread(β¦).start() (second block) everything works as expected.
Why was that? What is the difference between gevent.spawn() and Thread(β¦).start() ?
python multithreading gevent
David wolever
source share