6

foo条件が満たされた場合にのみ停止する機能があります。の実行中fooは、常にユーザー入力を求める必要があります (ユーザー入力を求め続けます)。互いに干渉せずに別々に実行してほしい。

以下の例では、foo「Hello」を出力しgetUserInput続け、ユーザー入力を探し続けます。ユーザー入力に何も入力しなくても、foo に hello を出力し続けてもらいたいです。ユーザーが文字「e」を入力しない限り、入力を求め続けます。以下に私の試みがあります:

import threading
from time import sleep

class test:
    def __init__(self):
        self.running = True

    def foo(self):
        while(self.running):
            print 'Hello\n'
            sleep(2)

    def getUserInput(self):
        x = ''
        while(x != 'e'):
            x = raw_input('Enter value: ')
        self.running = False

    def go(self):
        th1 = threading.Thread(target=self.foo)
        th2 = threading.Thread(target=self.getUserInput)
        th1.start()
        th2.start()


t = test()
t.go()

私のコードは最初の hello を出力して入力を求めますが、その後は何も要求しません。私は何を間違っていますか?事前にご協力いただきありがとうございます。

4

1 に答える 1

7

更新: オープナーは、IDLEのWindowsでコードを実行していました。I / Oに関しては、シェルやWindowsコマンドラインとは動作が異なります。彼のコードはWindowsコマンドラインで動作します。

原則として、あなたのコードは私のために働きます。Python2.6.5を実行しています。

ここにいくつかのコメント:

1)あなたの場合、メインスレッドともう1つのスレッドの2つのスレッドだけで十分です。ただし、3つでも機能します。メインスレッドは、他のスレッドが終了するのを待つ以外に何もしません。

join()2)スポーンするすべてのスレッドを明示的に行う必要があります。これは、終了する前にメインスレッドで行います。生成したスレッドを記録し(たとえば、リストにthreads)、プログラムの最後にそれらを結合します(たとえばfor t in threads: t.join())。

self.running3)スレッド間で変数を共有します。この場合は、1つのスレッドがそれを読み取るだけで、別のスレッドがそれを書き込むだけなので、問題ありません。一般に、共有変数には十分注意し、変更する前にロックを取得する必要があります。

4)メインスレッドで例外をキャッチKeyboardInterruptし、他のスレッドと通信して終了する方法を見つける必要があります:)

getUserInput5)小文字のメソッド名を使用するため、呼び出す代わりにget_user_input。大文字のクラス名を使用し、以下から継承しobjectます。class Test(object):

これは実行例です:

import threading
from time import sleep


def main():
    t = Test()
    t.go()
    try:
        join_threads(t.threads)
    except KeyboardInterrupt:
        print "\nKeyboardInterrupt catched."
        print "Terminate main thread."
        print "If only daemonic threads are left, terminate whole program."


class Test(object):
    def __init__(self):
        self.running = True
        self.threads = []

    def foo(self):
        while(self.running):
            print '\nHello\n'
            sleep(2)

    def get_user_input(self):
        while True:
            x = raw_input("Enter 'e' for exit: ")
            if x.lower() == 'e':
               self.running = False
               break

    def go(self):
        t1 = threading.Thread(target=self.foo)
        t2 = threading.Thread(target=self.get_user_input)
        # Make threads daemonic, i.e. terminate them when main thread
        # terminates. From: http://stackoverflow.com/a/3788243/145400
        t1.daemon = True
        t2.daemon = True
        t1.start()
        t2.start()
        self.threads.append(t1)
        self.threads.append(t2)


def join_threads(threads):
    """
    Join threads in interruptable fashion.
    From http://stackoverflow.com/a/9790882/145400
    """
    for t in threads:
        while t.isAlive():
            t.join(5)


if __name__ == "__main__":
    main()

eまたはEを入力すると、プログラムは少し遅れて終了します(意図したとおり)。ctrl + cを押すと、すぐに終了します。例外への応答を使用するプログラムを作成することはthreading、予想よりも少し注意が必要です。上記のソースに重要な参考資料を含めました。

実行時は次のようになります。

$ python supertest.py

Hello

Enter 'e' for exit: 
Hello


Hello


Hello

e
$
于 2012-09-11T19:13:57.840 に答える