如何在使用eventlet.monkey_patch()时创建非阻塞raw_input以及为什么它阻塞所有内容,即使在另一个线程上执行?

时间:2012-01-27 00:01:26

标签: python nonblocking raw-input eventlet

我写了这个最小代码来解释我的案例:

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)

即使我有2个线程,当我调用raw_input时它们都被阻塞。当我注释掉eventlet.monkey_patch()时,只有一个线程被阻止而另一个线程继续打印“打印”。我为什么要该做什么?

1 个答案:

答案 0 :(得分:2)

我想说这里有几点需要注意:

    {li> raw_input未被eventlet修补,因此其调用正在阻止
  • threadingeventlet修补,因此线程充当协同程序

解决此问题的一种方法是避免修补threading,以便线程是真正的线程。要做到这一点,你只需要替换:

eventlet.monkey_patch()

使用:

eventlet.monkey_patch(os=True,
                     select=True,
                     socket=True,
                     thread=False,
                     time=True)

请注意,当threadTrue时,会修补以下模块:threadthreadingQueue

编辑:如果您要修补threading并拥有异步raw_input,那么我建议采用以下实施方式:

def raw_input(message):
    sys.stdout.write(message)

    select.select([sys.stdin], [], [])
    return sys.stdin.readline()

这将轮询sys.stdin以检查它是否已准备好阅读。如果不是这种情况,它将控制eventlet以让其他协程执行。