簡體   English   中英

Python線程:同時運行2個不同的函數

[英]Python Threading: Running 2 different functions simultaneously

我有一個函數foo ,它只有在滿足條件后才會停止。 foo運行時,我需要一直要求用戶輸入(保持提示要求用戶輸入)。 我希望它們分開運行而不互相干擾。

在下面的示例中, foo繼續顯示“ Hello”,而getUserInput繼續查找用戶輸入。 我希望foo保持打印狀態,即使我沒有為用戶輸入輸入任何內容。 只要用戶不輸入字母“ 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()

我的代碼打印出第一個問候,並要求輸入,但此后什么也沒有。 我究竟做錯了什么? 感謝您的幫助。

更新: 開瓶器正在Windows中的IDLE中運行他的代碼。 關於I / O,其行為與Shell或Windows命令行不同。 他的代碼可在Windows命令行上使用。

原則上,您的代碼對我有用。 我正在運行Python 2.6.5。

這里有幾條評論:

1)在您的情況下,最好只有兩個線程:主線程和另一個線程。 但是,它也可以與三個一起使用。 只是您的主線程除了等待其他線程完成之外沒有其他操作。

2)您應該顯式join()生成的所有線程。 您可以在終止前在主線程中執行此操作。 記錄您產生的線程(例如,在列表threads ),然后在程序末尾將它們加入(例如, for t in threads: t.join() )。

3)您在線程之間共享變量self.running 在這種情況下很好,因為一個線程僅讀取它,而另一個僅寫入它。 通常,您需要非常小心共享變量並在更改它之前獲取一個鎖。

4)您應該在主線程中捕獲KeyboardInterrupt異常,並找到一種與其他線程進行通信以終止的方法:)

5)使用小寫的方法名稱,因此可以get_user_input代替getUserInput 使用大寫的類名並從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
$

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM