I wrote this minimum code to explain my case:
import threading
import time
import eventlet
eventlet.monkey_patch()
def printing_function():
while True:
# here i want to do some work
print "printing"
time.sleep(1)
if __name__ == '__main__':
thread = threading.Thread(target=printing_function)
thread.start()
while True:
# here i want to wait for users input
raw_input("raw input\n")
print "inside main loop"
time.sleep(1)
Even i have 2 threads, both of them are blocked when i call raw_input. When i comment out eventlet.monkey_patch(), only one thread is blocked and another keep printing "printing". Why and what should i do?
I'd say that there are a couple of things to note here:
raw_input
isn't patched byeventlet
, so its calls are blockingthreading
is patched byeventlet
, so threads are acting as coroutines
One way to workaround this would be to avoid patching threading
, so that threads are real threads. To do that, you just need to replace:
eventlet.monkey_patch()
with:
eventlet.monkey_patch(os=True,
select=True,
socket=True,
thread=False,
time=True)
Note that when thread
is True
the following modules are patched: thread
, threading
, Queue
.
Edit: If you want to patch threading
and have an asynchronous raw_input
, then I suggest the following implementation:
def raw_input(message):
sys.stdout.write(message)
select.select([sys.stdin], [], [])
return sys.stdin.readline()
This will poll sys.stdin
to check if it's ready for reading. If that's not the case, it will yield control to eventlet to let other coroutine execute.
来源:https://stackoverflow.com/questions/9027311/how-to-make-non-blocking-raw-input-when-using-eventlet-monkey-patch-and-why-it