天天看点

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的一个实现细节,你不应该因为不知道这一点而受到责备。我觉得你在解决这个问题的过程中学到了很多东西:)

这是非常正确的,我很高兴我遇到了这个问题。

并且不要忘记考虑接受答案;)晚安!