文档章节

线程中的setDaemon方法

o
 osc_fmg49rzg
发布于 2019/03/20 11:40
字数 1319
阅读 8
收藏 0
def

精选30+云产品,助力企业轻松上云!>>>

setDaemon方法必须在start方法前定义。t1.setDaemon(True),该语句的意思是:将主线程A设置为子线程t1的守护线程。也就是在执行程序时,t1会随着主线程A的退出而退出,不论t1是否执行完毕。

例1:当我们在程序中设置一个子线程并将其设为被守护线程时,那么该子线程会随着主线程的退出而退出,整个程序会在主线程执行结束后终止。

import threading
import time

def print_number(num):

    print("-----> %d" % num, time.ctime())
    time.sleep(5)
    print("print_number ending......", time.ctime())


t1 = threading.Thread(target=print_number,args=(10,))


if __name__ == '__main__':
    
    t1.setDaemon(True)
    
    t1.start()
    
    print("Main thread ended...")

输出结果如下:

-----> 10 Wed Mar 20 10:54:21 2019
Main thread ended...

***Repl Closed***

可以看到,主线程结束后,子线程t1的最后一句并未被打印出来,因为它随着主线程的退出而退出。

 

例2:当我们设置了多个子线程时,将其中一个子线程t1设置为被守护线程,那么只有t1会随着主线程的退出而退出,其他子线程不会受到影响,依然会被执行完毕。此时就会出现一种很奇怪的情况,如下所示:

import threading
import time

def print_number(num):

    print("-----> %d" % num, time.ctime())
    time.sleep(5)
    print("print_number ending......", time.ctime()) # 此处不应该被打印

def print_letter(letter):

    print("-----> %s" % letter, time.ctime())
    time.sleep(10)
    print("print_letter ending......", time.ctime()) 

t1 = threading.Thread(target=print_number,args=(10,))
t2 = threading.Thread(target=print_letter,args=('hello',))

if __name__ == '__main__':
    
    t1.setDaemon(True)

    t1.start()
    t2.start()

    print("Main thread ended...")

在这段代码中,我们设置了两个子线程:t1和t2,并将t1设置为被守护线程。按照上述解释,t1应该在主线程结束时一并推出,所以t1的最后一句“print("print_number ending......", time.ctime())” 不会被运行。但是结果却不是这样:

-----> 10 Wed Mar 20 10:58:00 2019
-----> hello Wed Mar 20 10:58:00 2019
Main thread ended...
print_number ending...... Wed Mar 20 10:58:05 2019 # t1线程的最后一行输出
print_letter ending...... Wed Mar 20 10:58:10 2019

***Repl Closed***

可以看到,在主线程最后一句输出“Main thread ended...”之后,t1的最后一行代码也被打印了,并不如我们所期待的那样,最后一句不被打印。这是因为什么呢?

此时我们一共存在着3个线程:主线程、子线程t1 和 t2。t1是被守护的子线程,它的执行时间是5秒;t2不是被守护线程,它的执行时间是10秒。由于t2并不被守护,所以在主线程打印最后一句"Main thread ended..."后,t2依然在执行。这是需要注意的是,虽然主线程的代码执行完毕了,但是主线程并未退出。它依然在后台运行并等待t2执行结束。我们所说的守护线程,是随着主线程的退出而一并退出的。但是,如果依然有其他子线程在运行,主线程并不会马上退出,它会等待所有子线程结束后才会推出。所以,我们看到,主线程虽然执行完毕(但在后台并未退出),被守护的t1(时间较短)依然会继续执行后面的代码,因为子线程t2还在运行,所以主线程依然在后台挂起。当子线程t2(时间较长)执行完毕并退出后,主线程才会退出。

 

代码执行完毕 并不等于 线程的退出。即使主线程没有任何代码需要执行,主线程仍会在后台运行,并等待所有的子线程退出后才会退出。

例3: 如果我们想看到随着主线程退出而子线程退出的情况,那么就可以将t2设置为守护线程。

import threading
import time

def print_number(num):

    print("-----> %d" % num, time.ctime())
    time.sleep(5)
    print("print_number ending......", time.ctime())

def print_letter(letter):

    print("-----> %s" % letter, time.ctime())
    time.sleep(10)
    print("print_letter ending......", time.ctime())

t1 = threading.Thread(target=print_number,args=(10,))
t2 = threading.Thread(target=print_letter,args=('hello',))

if __name__ == '__main__':
    
    t2.setDaemon(True) # 将执行时间较长的t2设置为守护线程

    t1.start()
    t2.start()

    print("Main thread ended...")

 运行结果如下所示:

-----> 10 Wed Mar 20 11:24:59 2019
-----> hello Wed Mar 20 11:24:59 2019
Main thread ended... # 主线程执行完毕,并未退出,等待其他子线程(t1)执行
print_number ending...... Wed Mar 20 11:25:04 2019 # 线程t1执行完毕并退出

***Repl Closed***

由于t1比t2的执行时间短,所以t1会先执行完毕并推出。而t2为被守护线程,所以它会随着主线程的退出而退出。在t1执行完毕并退出后,主线程不需要再等待其他子线程了,所以主线程就会退出,而t2会随着主线程一并退出,因此t2中的最后一行代码没有被执行。

 

join方法与setDaemon方法本质上是作用相反的两个方法:

1、join方法:t1.join--->是将t1的优先级提高,阻塞主线程,等待t1执行结束后再执行主线程以及其他子线程。

2、setDaemon方法:t1.setDaemon(True)--->是将t1捆绑到主线程上,它会随着主线程的退出而退出,并不考虑自己的代码是否执行完毕。所以对于t1来说,主线程的优先级更高。

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
Python中threading的join和setDaemon的区别[带例子]

python的进程和线程经常用到,之前一直不明白threading的join和setDaemon的区别和用法,今天特地研究了一下。multiprocessing中也有这两个方法,同样适用,这里以threading的join和setDaemon...

osc_x2c17gwy
2019/01/16
4
0
python多线程(线程的合并与后台线程)

线程的合并 python的Thread类中还提供了join()方法,使得一个线程可以等待另一个线程执行结束后再继续运行。这个方法还可以设定一个timeout参数,避免无休止的等待。因为两个线程顺序完成,看...

DragonRiver2015
2013/12/07
140
0
python线程join方法与seDaemon方法

前言 基于上篇文章之后,我们了解了python程序执行流程,为什么要使用线程,以及什么情况下使用python线程,本文继此之后说说python多线程编程时,经常用到的join()和setDaemon()方法. join()方法...

dyc2005
2017/11/29
0
0
彻底理解Python多线程中的setDaemon与join【配有GIF示意】

在进行Python多线程编程时, join() 和 setDaemon() 是最常用的方法,下面说说两者的用法和区别。 1、join () 例子:主线程A中,创建了子线程B,并且在主线程A中调用了B.join(), 那么,主线...

osc_je020lv0
2019/11/02
2
0

没有更多内容

加载失败,请刷新页面

加载更多

在Bash脚本中,如果发生某种情况,如何退出整个脚本?

问题: I'm writing a script in Bash to test some code. 我正在Bash中编写脚本来测试一些代码。 However, it seems silly to run the tests if compiling the code fails in the first pl......

技术盛宴
12分钟前
11
0
Windows安装Python+OpenCV

1、更新PyCharm中pip来源,使用清华和阿里云:https://pypi.tuna.tsinghua.edu.cn/simple/ http://mirrors.aliyun.com/pypi/simple/ 2、PyCharm查看已安装packets,添加新的安装包,从pip云端...

极客行
35分钟前
17
0
tomcat8配置虚拟目录,实现一个tomcat运行两个项目, tomcat配置URL不区分大小写

<?xml version="1.0" encoding="UTF-8"?><!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distri......

青峰Jun19er
41分钟前
19
0
HBase和MySQL存储方式的差别?或者说是,行存储和列存储的区别?

HBase借鉴列存储的思想,但是最底层依然是依靠键值对来存储数据,HBase为非关系型数据库 而MySQL则是行存储,MySQL为关系型数据库 写过程 行存储因为数据是连续的,所以只需要进行追加即可;...

其乐m
46分钟前
25
0
一个老程序员在互联网寒冬下的感悟

1. 你千万不要认为学习技术就可以换来稳定的生活和高的薪水待遇,你更不要认为那些从事市场开发,跑腿的人,没有前途。 不清楚你是不是知道,咱们中国有相当大的一部分软件公司,他们的软件开...

北柠Java
50分钟前
39
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部