python, веселый бизнес с потоками и IDE? - PullRequest
0 голосов
/ 11 февраля 2009

Может я не могу делать то, что хочу? Я хочу, чтобы 1 поток выполнял все, что ему нужно, и 2-й поток, чтобы восстановить пользовательский ввод, чтобы установить флаг выхода. используя этот код, я хочу ввести q в любое время, чтобы выйти или сделать тайм-аут после печати эй 6 раз

import sys
import threading
import time

class MyThread ( threading.Thread ):
    def run (s):
        try:
            s.wantQuit = 0
            while(not s.wantQuit):
                print "want input"
                button = raw_input()
                if button == "q":
                    s.wantQuit=1
        except KeyboardInterrupt:
            s.wantQuit = 1
            print "abort with KeyboardInterrupt"
        print "done mythread"

myThread = MyThread ()
myThread.start()

a=5
while not myThread.wantQuit:
    print "hey"
    if (a == 0):
        break;
    a = a-1;
    time.sleep(1)
myThread.wantQuit=1
print "main thread done"

что происходит, вместо двух потоков, у меня есть основной, печатающий 4/6 раз, затем всплывает диалоговое окно с запросом ввода и приложение блокируется до тех пор, пока я его не введу. WTF ?!

want input
hey
hey
hey
hey
abort with KeyboardInterrupt
done mythread
main thread done

Я использую PyScripter (он имеет отладку), я также пробовал pydle, который, кажется, не позволяет мне вводить данные и в конечном итоге блокируется после его запуска один раз.

1 Ответ

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

Проблема здесь в том, что raw_input ожидает ввода, чтобы очистить входной поток; проверить его документацию . PyScripter, вероятно, видит, что программа ожидает ввода и выдает вам поле ввода (не знаю точно, никогда не использовал его).

Программа работает точно так, как я ожидаю от командной строки; вторичный поток блокируется на raw_input, пока я не нажму "q [enter]", после чего программа завершится.

Это не так, AFAICS, легко проверить и посмотреть, доступен ли символ во входном потоке, прежде чем блокировать вызов чтения. Вы, вероятно, должны проверить эту ветку о том, как читать символ блокирующим способом без необходимости ввода [enter], а затем этот пост о проблеме чтения символа без блокирования при все.

Возможно, вы можете использовать комбинацию msvcrt.kbhit в Windows и этот рецепт из FAQ по Python, чтобы получить символ q без необходимости нажатия клавиш, но я оставлю это в качестве упражнения для читателя .

Приложение: Одна вещь, которую вы могли бы сделать, это использовать библиотеку select, чтобы установить тайм-аут при чтении с клавиатуры, что сделает вашу программу более ожидаемой:

import sys
import threading
import time
import select

def timeout_read(n_chars):
  r, _, _ = select.select([sys.stdin], [], [], 1)
  return r[0].read(n_chars) if r else ""

class MyThread (threading.Thread):
    def run (self):
        try:
            self.wantQuit = 0
            while not self.wantQuit:
                print "want input"
                button = timeout_read(1)
                if button == "q":
                    self.wantQuit=1
        except KeyboardInterrupt:
            self.wantQuit = 1
            print "abort with KeyboardInterrupt"
        print "done mythread"

myThread = MyThread ()
myThread.start()

a=5
while not myThread.wantQuit:
    print "hey"
    if (a == 0):
        break;
    a = a-1;
    time.sleep(1)
myThread.wantQuit=1
print "main thread done"

Обратите внимание, что вам все равно нужно будет нажать "q [enter]" с этим решением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...