如何在使用eventlet.monkey_patch()时实现非阻塞的raw_input,为什么它会阻塞一切,尽管在另一个线程中执行?
我写了这段简单的代码来说明我的情况:
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)
即使我有两个线程,当我调用 raw_input 时,它们都被阻塞了。当我把 eventlet.monkey_patch() 注释掉时,只有一个线程被阻塞,另一个线程还在不停地打印“printing”。这是为什么呢?我该怎么做?
1 个回答
2
我觉得这里有几点需要注意:
raw_input
没有被eventlet
修改,所以它的调用会阻塞,也就是说在等待输入时会停下来。threading
被eventlet
修改了,所以线程的行为就像协程一样。
解决这个问题的一种方法是避免修改 threading
,这样线程就会变成真正的线程。要做到这一点,你只需要把:
eventlet.monkey_patch()
替换成:
eventlet.monkey_patch(os=True,
select=True,
socket=True,
thread=False,
time=True)
注意,当 thread
设置为 True
时,以下模块会被修改: thread
、threading
、Queue
。
补充:如果你想修改 threading
并且让 raw_input
支持异步操作,那么我建议使用以下实现:
def raw_input(message):
sys.stdout.write(message)
select.select([sys.stdin], [], [])
return sys.stdin.readline()
这个实现会检查 sys.stdin
是否准备好读取。如果没有准备好,它会把控制权交给 eventlet
,让其他协程执行。