本文介绍了当使用eventlet.monkey_patch()时,如何使非阻塞raw_input成为一个对象,为什么它阻塞所有内容,即使在另一个线程上执行时也是如此?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了以下最小代码来解释我的情况:

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)

即使我有2个线程,当我调用raw_input时,它们都被阻塞.当我注释掉eventlet.monkey_patch()时,只有一个线程被阻止,而另一个线程继续打印正在打印".为什么以及我该怎么办?

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没有被eventlet修补,因此其调用被阻止
  • threadingeventlet修补,因此线程充当协程
  • raw_input isn't patched by eventlet, so its calls are blocking
  • threading is patched by eventlet, so threads are acting as coroutines

解决此问题的一种方法是避免打补丁threading,这样线程才是真正的线程.为此,您只需替换:

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()

具有:

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

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

Note that when thread is True the following modules are patched: thread, threading, Queue.

如果要修补threading并具有异步raw_input,则建议采用以下实现:

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()

这将轮询sys.stdin,以检查是否可以读取.如果不是这种情况,它将控制eventlet以便执行其他协程.

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.

这篇关于当使用eventlet.monkey_patch()时,如何使非阻塞raw_input成为一个对象,为什么它阻塞所有内容,即使在另一个线程上执行时也是如此?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-01 19:28