выход питона из блокирующего потока? - PullRequest
2 голосов
/ 16 февраля 2009

В моем коде я зацикливаюсь, хотя raw_input(), чтобы увидеть, просил ли пользователь выйти. Мое приложение может выйти до того, как пользователь завершит работу, но моя проблема в том, что приложение все еще живо, пока я не введу ключ для возврата из функции блокировки raw_input(). Могу ли я заставить raw_input() вернуться, возможно, отправив ему поддельный ввод? Могу ли я прекратить тему, на которой он находится? (единственные данные, которые он имеет, - это единственная переменная с именем wantQuit).

Ответы [ 4 ]

6 голосов
/ 16 февраля 2009

Почему бы вам просто не отметить поток как демонический?

Из документов :

Поток может быть помечен как «поток демона». Значение этого флага заключается в том, что вся программа Python завершается, когда остаются только потоки демона. Начальное значение наследуется от потока создания. Флаг можно установить с помощью атрибута демона.

2 голосов
/ 16 февраля 2009

Вы можете использовать эту функцию тайм-аута, которая упаковывает вашу функцию. Вот рецепт от: http://code.activestate.com/recipes/473878/

def timeout(func, args=(), kwargs={}, timeout_duration=1, default=None):
    '''This function will spwan a thread and run the given function using the args, kwargs and 
    return the given default value if the timeout_duration is exceeded 
    ''' 
    import threading
    class InterruptableThread(threading.Thread):
        def __init__(self):
            threading.Thread.__init__(self)
            self.result = default
        def run(self):
            try:
                self.result = func(*args, **kwargs)
            except:
                self.result = default
    it = InterruptableThread()
    it.start()
    it.join(timeout_duration)
    if it.isAlive():
        return it.result
    else:
        return it.result
2 голосов
/ 16 февраля 2009

Вы можете использовать неблокирующую функцию для чтения ввода пользователя.
Это решение для Windows:

import msvcrt
import time

while True:
    # test if there are keypresses in the input buffer
    while msvcrt.kbhit(): 
        # read a character
        print msvcrt.getch()
    # no keypresses, sleep for a while...
    time.sleep(1)

Чтобы сделать что-то подобное в Unix, который читает строку за раз, в отличие от версии для Windows, читающей char по char (спасибо Aaron Digulla за предоставление ссылки на форум пользователей python):

import sys
import select

i = 0
while i < 10:
    i = i + 1
    r,w,x = select.select([sys.stdin.fileno()],[],[],2)
    if len(r) != 0:
        print sys.stdin.readline()

Смотри также: http://code.activestate.com/recipes/134892/

1 голос
/ 16 февраля 2009

В списке рассылки Python есть запись , в которой объясняется, как это сделать для Unix:

# this works on some platforms:

import signal, sys

def alarm_handler(*args):
    raise Exception("timeout")

def function_xyz(prompt, timeout):
    signal.signal(signal.SIGALRM, alarm_handler)
    signal.alarm(timeout)
    sys.stdout.write(prompt)
    sys.stdout.flush()
    try:
        text = sys.stdin.readline()
    except:
        text = ""
    signal.alarm(0)
    return text
...