天天看點

python如何同時運作兩個函數_關于多線程:Python線程:同時運作2個不同的函數...

我有一個函數foo,隻有在滿足條件後才會停止。 當foo正在運作時,我需要一直詢問使用者輸入(不斷詢問使用者輸入)。 我希望它們分開運作而不會互相幹擾。

在下面的示例中,foo繼續列印"Hello",getUserInput一直在尋找使用者輸入。 即使我沒有為使用者輸入輸入任何内容,我也希望foo繼續列印你好。 隻要使用者沒有輸入字母'e',它就會一直詢問輸入。 我有以下嘗試:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28import threading

from time import sleep

class test:

def __init__(self):

self.running = True

def foo(self):

while(self.running):

print 'Hello

'

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()

我的代碼列印出第一個問候語并要求輸入,但之後沒有任何内容。 我究竟做錯了什麼? 感謝您的幫助。

對我來說很好。

如果你根本不輸入任何東西,它還能繼續列印你好嗎?

是的,每2秒一次。

你在運作哪個版本的python?

OSX 10.6.8上的2.6.1。 也适用于2.5.4和2.7.2。

那對我來說這對我來說很奇怪。 我在Windows 7上有32位python,2.7.2(64位,我的一些子產品與64位不相容,是以32位python)。 謝謝你順便提一下。

在python 2.7.2 FreeBSD amd64(64位)上運作正常。

我在另一台機器上運作它,我遇到了同樣的問題。 也許我沒有正确澄清我的目标/目标。 我希望兩個線程彼此獨立運作,無論輸入是否輸入,你每2秒列印一次hello。 目前,除非我輸入一些輸入,否則它不會列印下一個問候語。

更新:開啟者在IDLE上的Windows上運作他的代碼。關于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)使用小寫方法名稱,是以代替getUserInput将其命名為get_user_input。使用大寫的類名并從object繼承:class Test(object):

這是一個運作的例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60import threading

from time import sleep

def main():

t = Test()

t.go()

try:

join_threads(t.threads)

except KeyboardInterrupt:

print"

KeyboardInterrupt 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 '

Hello

'

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響應異常的程式比預期的要複雜一些。我在上面的源代碼中包含了重要的參考資料。

這是它在運作時的樣子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15$ python supertest.py

Hello

Enter 'e' for exit:

Hello

Hello

Hello

e

$

謝謝,我一定會記住這一切。

非常感謝。我非常感謝你的努力。我現在使用的是Python 3.2.3,即使使用你的代碼,我仍然會遇到相同的行為。你好列印一次,然後控制台隻是等待我的輸入而沒有任何連續列印你好。有什麼想法嗎?

你可以在你的系統上執行Python 2.7上的代碼嗎?

我将再次編輯答案,并向您展示輸出的樣子。編輯:完成。

是的我在2.7以及2個不同硬體上的Python 3上嘗試過它。

你如何調用該腳本?從Windows指令行或您是否使用IDLE?

我正在與IDLE合作。一旦我輸入一些輸入,即使在32位Windows XP上,它也隻列印下一個問候

IDLE是一個非常特殊的環境。它是為了發展,而不是為了生産。請從windows指令行運作代碼:c:\path\to\python.exe test.py

IDLE可能在等待輸入時阻塞輸出。是以你的線程可能正在嘗試列印你好,但空閑不會讓它直到輸入得到解決。是的,在指令行中運作它

這是令人尴尬的,是的,現在确實有效。非常感謝。我要確定從現在開始從指令行運作所有内容。我還在學習python :)

@AasamTasaddaq,這很好。它是IDLE的一個實作細節,你不應該因為不知道這一點而受到責備。我覺得你在解決這個問題的過程中學到了很多東西:)

這是非常正确的,我很高興我遇到了這個問題。

并且不要忘記考慮接受答案;)晚安!