Python线程/守护程序

时间:2015-04-30 06:10:05

标签: python multithreading daemon

自学成才的编程学生,所以我为所有的业余错误道歉。我想学习一些更深层次的主题,所以我试图理解线程和异常处理。

import threading
import sys
from time import sleep
from random import randint as r

def waiter(n):
    print "Starting thread " + str(n)
    wait_time = r(1,10)
    sleep(wait_time)
    print "Exiting thread " + str(n)

if __name__=='__main__':
    try:
        for i in range(5):
            t = threading.Thread(target=waiter, args=(i+1,))
            t.daemon = True
            t.start()
            sleep(3)
        print 'All threads complete!'
        sys.exit(1)
    except KeyboardInterrupt:
        print ''
        sys.exit(1)

此脚本在随机时间后启动和停止线程,如果收到^C,将终止该程序。我注意到当某些线程完成时它不会打印出来:

Starting thread 1
Starting thread 2
Starting thread 3
Exiting thread 3
Exiting thread 2
Starting thread 4
Exiting thread 1
Exiting thread 4
Starting thread 5
All threads complete!

在这个例子中,它永远不会声明它退出线程5.我发现如果我注释掉t.daemon = True语句,我可以解决这个问题,但是异常处理会等待任何线程完成。

Starting thread 1
Starting thread 2
^C
Exiting thread 1
Exiting thread 2

我可以理解,在处理线程时,最好是在退出之前完成他们处理的内容,但我只是好奇为什么会这样。我非常感谢有关线程和守护进程性质的任何答案,以指导我的理解。

1 个答案:

答案 0 :(得分:4)

守护程序线程的整个是,如果在主线程完成时它没有完成,它将被立即终止。引用the docs

  

线程可以标记为“守护程序线程”。这个标志的意义在于,当只剩下守护进程线程时,整个Python程序都会退出。初始值继承自创建线程。可以通过守护进程属性或守护进程构造函数参数设置该标志。

     

注意守护程序线程在关闭时突然停止。他们的资源(例如打开文件,数据库事务等)可能无法正确发布。如果您希望线程正常停止,请使它们成为非守护进程并使用合适的信号机制,例如事件。

现在,看看你的逻辑。主线程仅在启动线程5后休眠3秒钟。但是线程5可以在1-10秒内休眠。因此,大约70%的时间,它不会在主线程唤醒时完成,打印"所有线程完成!"并退出。但是线程5仍然睡了5秒钟。在这种情况下,线程5将被杀死,而不会打印"退出线程5"。

如果这不是您想要的行为 - 如果您希望主线程等待所有线程完成 - 那么就不要使用守护程序线程。

相关问题