Python线程:同时运行两个不同的函数

2024-09-25 00:21:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个函数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并请求输入,但之后什么也不输入。我做错什么了?提前谢谢你的帮助。


Tags: 用户testimportselfgohellofoodef
1条回答
网友
1楼 · 发布于 2024-09-25 00:21:38

更新:打开程序正在空闲的Windows上运行其代码。关于I/O,它的行为与shell或Windows命令行不同。他的代码在Windows命令行上运行。

原则上,你的代码对我有效。我正在运行Python2.6.5。

这里有几点意见:

1)在你的情况下,最好只有两个线程:主线程和另一个线程。不过,它也将与三个工作。只是你的主线程只会等待其他线程完成。

2)应该显式地join()生成的所有线程。在终止主线程之前,在主线程中执行此操作。记录生成的线程(例如在列表中),然后在程序结束时加入它们(例如for t in threads: t.join())。

3)在线程之间共享变量self.running。在这种情况下是可以的,因为一个线程只读它,另一个线程只写它。一般来说,您需要非常小心共享变量,并在更改之前获取一个锁。

4)您应该捕获主线程中的KeyboardInterrupt异常,并找到与其他线程通信的方法来终止:)

5)使用小写的方法名,所以不要调用getUserInput,而是调用get_user_input。使用大写类名并从objectclass 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
$

相关问题 更多 >