Как сделать неблокирующим raw_input при использовании eventlet.monkey_patch() и почему он блокирует все, даже когда выполняется в другом потоке?
Я написал этот минимальный код, чтобы объяснить мой случай:
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 ответ
Я бы сказал, что здесь нужно отметить пару вещей:
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, чтобы позволить другим сопрограммам исполниться.