美文网首页
python 线程 join()和setDaemon()的区别

python 线程 join()和setDaemon()的区别

作者: Mikasa___ | 来源:发表于2019-06-12 10:05 被阅读0次

一般多线程无线程锁的情况下,几个线程会互相抢资源,同时操作数据或执行各自的方法

import threading
import time
class MyThread(threading.Thread):
        def __init__(self,id):
                threading.Thread.__init__(self)
                self.id = id
        def run(self):
                x = 0
                time.sleep(10)
                print self.id
 
if __name__ == "__main__":
        t1=MyThread(999)
        t1.start()
        for i in range(5):
                print i

t1.start() 后会去调用MyThread()方法,代码继续往下走,循环输出0-4,因为MyThread()里面线程会休眠一段时间,所以可以从结果中看出来两线程的结果是分先后的

0
1
2
3
4

此时会停一段时间

999

下面进入正题,join()和setDaemon()通过不同方式控制线程之间的执行顺序和存活时间


image.png

主线程运行过程中,需要插入一个子线程,且子线程运行结束后,主线程才能继续运行或停止,此时用join()方法

import threading
import time
class MyThread(threading.Thread):
        def __init__(self,id):
                threading.Thread.__init__(self)
                self.id = id
        def run(self):
                x = 0
                time.sleep(10)
                print self.id
 
if __name__ == "__main__":
        t1=MyThread(999)
        t1.start()
        t1.join()
        for i in range(5):
                print i

先sleep(10)停一段时间

999
0
1
2
3
4
join方法有个 timeout 参数,表示主线程会等待多长时间,时间一到,不管子线程是否执行完毕(此时判断子线程是否仍在执行,可以用 is_alive()),主线程继续执行至结束

主线程运行过程中,插入了一个子线程,不管子线程运行如何都不会影响到主线程的继续或结束

daemon
import threading
import time
class MyThread(threading.Thread):
        def __init__(self,id):
                threading.Thread.__init__(self)
                self.id = id
        def run(self):
                x = 0
                time.sleep(10)
                print self.id
 
if __name__ == "__main__":
        t1=MyThread(999)
        t1.setDaemon(True)
        t1.start()
        for i in range(5):
                print i

执行结果

0
1
2
3
4
setDaemon(True)的是打印999的线程,它变为守护线程,后面打印0-4的线程可以看做是主线程,走完打印0-4完成后退出,子线程打印999的也一起退出不会再执行

setDaemon() :默认False不回收,需要在 start 方法前调用; 设为True相当于向主线程中注册守护线程,主线程结束时会将其一并回收。
Daemon进程通常为后台长期运行,执行某一项相对独立的任务,或提供某一种服务的进程,随系统启停而启停。
如果主线程是永远都不会结束的,那设置一个线程为守护线程是没必要的,设不设置都一样。
如果希望子线程一直运行,可以把子线程的代码写在while True里面一直循环,但同时要设置为守护线程,不然主线程结束了,子线程还一直运行,程序结束不了。

测试代码:


注掉setDaemon,设置超时时间,主线程跑完子线程还在跑,子线程跑完再退出.png
注掉setDaemon,不设置超时时间,子线程跑结束主线程跑,主线程跑完退出.png setDaemon() & join()不设置超时参数,子线程全跑结束了主线程跑,主线程跑完退出.png
setDaemon() & join()设置超时参数,子线程主线程都跑,主线程结束子线程还存活,子线程没再跑完程序退出.png

相关文章

网友评论

      本文标题:python 线程 join()和setDaemon()的区别

      本文链接:https://www.haomeiwen.com/subject/rhkcfctx.html