Python线程脚本无法正常启动/工作

时间:2014-09-06 09:05:12

标签: python multithreading python-2.7 daemon sys

我很快为stackoverflow编写了这个示例脚本,所以忽略它的功能方面(我的版本看起来比这更好),但是:

from threading import Thread
from msvcrt import getch       #I'm using Windows by the way.
from time import sleep
import sys

def KeyEvent():
    while True:
        key = getch()
        if key.encode('hex') == '03': #^C
            y = raw_input("Are you sure you want to quit? (y/n): ").lower()
            if y == 'y':
                sys.exit(0)
            else: pass

def main():
    t = 0
    while True:
        print "The count is {0}".format(t)
        t +=1
        sleep(1)

if __name__ == "__main__":
    mainthread = Thread(target = main)
    kev = Thread(target = KeyEvent)

    mainthread.daemon = True
    kev.daemon = True

    mainthread.start()
    kev.start()

这个脚本应该做的是同时运行两个循环,一个以秒为单位计数,而另一个检查^ C.请不要建议我使用其他方法,因为这是一个例子。

我的问题是,脚本无法启动。它显示“计数为0”并退出,但如果我完全省略.daemon = True部分,则脚本会运行,但它不能正确运行sys.exit(0)。如何使此脚本正确运行并在出现提示时退出?

2 个答案:

答案 0 :(得分:2)

标记为daemon的线程在每个其他非守护程序线程死亡时自动死亡。在你的情况下,主线程在你的两个守护进程线程上调用start()后就死了,带来了python进程。在你的线程中完成任何事情都是运气和时间问题。

sys.exit(0)不会杀死主线程以外的线程。你需要一种方法来告知你的线程是时候停止了。一种方法是通过Event对象。

你不应该使用getch来尝试捕捉Ctrl + C,而是尝试使用信号处理程序:

from threading import Thread
from threading import Event
from time import sleep
import signal

stop = Event()

def handler(signum, frame):
    y = raw_input("Are you sure you want to quit? (y/n): ").lower()
    if y == 'y':
        stop.set()

def main():
    t = 0
    while not stop.isSet():
        print "The count is {0}".format(t)
        t +=1
        sleep(1)

if __name__ == "__main__":
    signal.signal(signal.SIGINT, handler)

    mainthread = Thread(target = main)
    mainthread.start()

    while mainthread.is_alive():
        try:
            mainthread.join(timeout = 0.1)
        except IOError:
            pass #Gets thrown when we interrupt the join

答案 1 :(得分:0)

你有两个问题。首先,你的课程结束得太早。其次是你试图退出KeyEvent线程中的程序。

您的程序提前终止,因为您没有保留主线程。您的主线程在您的最后一个语句kev.start()之后立即结束,并且您的守护程序线程随之死亡。

您需要一种机制来无限地保存主线程(因为您希望用户键入“y”以退出。)有几种方法可以执行此操作。一个是添加

mainthread.join()

到代码的末尾。

其次,KeyEvent线程中的sys.exit(0)显然无法终止整个程序。请在以下帖子中找到您的答案:Why does sys.exit() not exit when called inside a thread in Python?