python多线程之t.setDaemon(True) 和 t.join()
0.目录
1.参考
2.结论
(1)通过 t.setDaemon(True) 将子线程设置为守护进程(默认False),主线程代码执行完毕后,python程序退出,无需理会守护子线程的状态。
(2) t.join() 用于阻塞主线程,可以想象成将某个子线程的执行过程插入(join)到主线程的时间线上,主线程的后续代码延后执行。注意和 t.start() 分开写在两个for循环中。
(3)第一个for循环同时启动了所有子线程,随后在第二个for循环中执行t.join() ,主线程实际被阻塞的总时长==其中执行时间最长的一个子线程。
3.验证过程
1.参考
C:\Program Files\Anaconda2\Lib\threading.py
def daemon(self):
"""A boolean value indicating whether this thread is a daemon thread (True) or not (False). This must be set before start() is called, otherwise RuntimeError is
raised. Its initial value is inherited from the creating thread; the
main thread is not a daemon thread and therefore all threads created in
the main thread default to daemon = False. The entire Python program exits when no alive non-daemon threads are
left. """
def join(self, timeout=None):
"""Wait until the thread terminates. This blocks the calling thread until the thread whose join() method is
called terminates -- either normally or through an unhandled exception
or until the optional timeout occurs. When the timeout argument is present and not None, it should be a
floating point number specifying a timeout for the operation in seconds
(or fractions thereof). As join() always returns None, you must call
isAlive() after join() to decide whether a timeout happened -- if the
thread is still alive, the join() call timed out. When the timeout argument is not present or None, the operation will
block until the thread terminates. A thread can be join()ed many times. join() raises a RuntimeError if an attempt is made to join the current
thread as that would cause a deadlock. It is also an error to join() a
thread before it has been started and attempts to do so raises the same
exception. """
2.结论
(1)通过 t.setDaemon(True) 将子线程设置为守护进程(默认False),主线程代码执行完毕后,python程序退出,无需理会守护子线程的状态。
(2) t.join() 用于阻塞主线程,可以想象成将某个子线程的执行过程插入(join)到主线程的时间线上,主线程的后续代码延后执行。注意和 t.start() 分开写在两个for循环中。
(3)第一个for循环同时启动了所有子线程,随后在第二个for循环中执行t.join() ,主线程实际被阻塞的总时长==其中执行时间最长的一个子线程。
3.验证过程
(1)子线程默认为【非守护线程】,主线程代码执行完毕,各子线程继续运行,直到所有【非守护线程】结束,python程序退出。
#!usr/bin/env python
#coding:utf-8
import time
import random
import logging import thread
import threading
from Queue import Queue lock = threading.Lock() #'function-call ownership'
rlock = threading.RLock() #thread ownership def get_logger():
logger = logging.getLogger("threading_example")
logger.setLevel(logging.DEBUG) # fh = logging.FileHandler("d:/threading.log")
fh = logging.StreamHandler()
fmt = '%(asctime)s - %(threadName)-10s - %(levelname)s - %(message)s'
formatter = logging.Formatter(fmt)
fh.setFormatter(formatter) logger.addHandler(fh)
return logger
logger = get_logger()
################################# class MyThread(threading.Thread):
def __init__(self, number):
threading.Thread.__init__(self)
self.number = number
def run(self):
for i in range(2):
logger.debug(i)
time.sleep(self.number) def main():
logger.debug('MainThread Start')
threads = [MyThread(3-i) for i in range(3)] for t in threads:
t.start() logger.debug('MainThread End') if __name__ == '__main__':
main()
输出:
2017-08-15 17:04:12,512 - MainThread - DEBUG - MainThread Start
2017-08-15 17:04:12,512 - Thread-1 - DEBUG - 0
2017-08-15 17:04:12,513 - Thread-2 - DEBUG - 0
2017-08-15 17:04:12,513 - Thread-3 - DEBUG - 0
2017-08-15 17:04:12,513 - MainThread - DEBUG - MainThread End
2017-08-15 17:04:13,513 - Thread-3 - DEBUG - 1
2017-08-15 17:04:14,513 - Thread-2 - DEBUG - 1
2017-08-15 17:04:15,513 - Thread-1 - DEBUG - 1
(2) t.setDaemon(True), 主线程代码执行完毕,直接退出python程序,无需理会【守护】子线程的状态。
def main():
logger.debug('MainThread Start')
threads = [MyThread(3-i) for i in range(3)] for t in threads:
t.setDaemon(True) #将子线程设置为守护进程
t.start() logger.debug('MainThread End')
输出:
2017-08-15 17:06:20,822 - MainThread - DEBUG - MainThread Start
2017-08-15 17:06:20,822 - Thread-1 - DEBUG - 0
2017-08-15 17:06:20,823 - Thread-2 - DEBUG - 0
2017-08-15 17:06:20,823 - MainThread - DEBUG - MainThread End
2017-08-15 17:06:20,823 - Thread-3 - DEBUG - 0
(3)错误用法: d t1.join()阻塞了主线程的for循环,t1结束后才执行t2.start()...实际就变成了单线程顺序执行。
def main():
logger.debug('MainThread Start')
threads = [MyThread(3-i) for i in range(3)] for t in threads:
t.start()
t.join()
logger.debug('{} start() join() activeCount: {}'.format(t.getName(), threading.activeCount())) logger.debug('MainThread End')
输出:
2017-08-15 17:17:38,219 - MainThread - DEBUG - MainThread Start
2017-08-15 17:17:38,230 - Thread-1 - DEBUG - 0
2017-08-15 17:17:41,230 - Thread-1 - DEBUG - 1
2017-08-15 17:17:44,232 - MainThread - DEBUG - Thread-1 start() join() activeCount: 1
2017-08-15 17:17:44,232 - Thread-2 - DEBUG - 0
2017-08-15 17:17:46,232 - Thread-2 - DEBUG - 1
2017-08-15 17:17:48,233 - MainThread - DEBUG - Thread-2 start() join() activeCount: 1
2017-08-15 17:17:48,233 - Thread-3 - DEBUG - 0
2017-08-15 17:17:49,234 - Thread-3 - DEBUG - 1
2017-08-15 17:17:50,234 - MainThread - DEBUG - Thread-3 start() join() activeCount: 1
2017-08-15 17:17:50,234 - MainThread - DEBUG - MainThread End
(4)异常用法:只对for循环的最后一个子线程执行了t.join() ,如果该子线程的执行时长不是所有子线程中最久的,可能达不到预期效果。
def main():
logger.debug('MainThread Start')
# threads = [MyThread(3-i) for i in range(3)]
threads = [MyThread((3-i)*2) for i in range(3)] #修改了等待时间 for t in threads:
t.start() logger.debug('MainThread ing')
# for t in threads:
t.join()
logger.debug('{} is_alive: {} join() activeCount: {}'.format(t.getName(), t.is_alive(), threading.activeCount()))
logger.debug('MainThread End')
输出:
2017-08-15 18:18:10,924 - MainThread - DEBUG - MainThread Start
2017-08-15 18:18:10,927 - Thread-1 - DEBUG - 0
2017-08-15 18:18:10,930 - Thread-2 - DEBUG - 0
2017-08-15 18:18:10,931 - Thread-3 - DEBUG - 0
2017-08-15 18:18:10,931 - MainThread - DEBUG - MainThread ing
2017-08-15 18:18:12,931 - Thread-3 - DEBUG - 1
2017-08-15 18:18:14,931 - Thread-2 - DEBUG - 1
2017-08-15 18:18:14,931 - MainThread - DEBUG - Thread-3 is_alive: False join() activeCount: 3
2017-08-15 18:18:14,931 - MainThread - DEBUG - MainThread End
2017-08-15 18:18:16,928 - Thread-1 - DEBUG - 1
(5)正常用法:第二个for循环保证每一个子线程都执行了t.join(), 虽然t1运行结束后才执行t2.join(), 但是第一个for循环已经启动了所有子线程,所以主线程实际被阻塞的总时长==其中执行时间最长的一个子线程。
def main():
logger.debug('MainThread Start')
# threads = [MyThread(3-i) for i in range(3)]
threads = [MyThread((i+1)*2) for i in range(3)] #修改了等待时间 for t in threads:
t.start() logger.debug('MainThread ing')
for t in threads:
logger.debug('{} is_alive: {} join() activeCount: {}'.format(t.getName(), t.is_alive(), threading.activeCount()))
t.join()
logger.debug('MainThread End')
输出:
2017-08-15 17:30:00,499 - MainThread - DEBUG - MainThread Start
2017-08-15 17:30:00,499 - Thread-1 - DEBUG - 0
2017-08-15 17:30:00,500 - Thread-2 - DEBUG - 0
2017-08-15 17:30:00,500 - Thread-3 - DEBUG - 0
2017-08-15 17:30:00,500 - MainThread - DEBUG - MainThread ing
2017-08-15 17:30:00,500 - MainThread - DEBUG - Thread-1 is_alive: True join() activeCount: 4
2017-08-15 17:30:02,500 - Thread-1 - DEBUG - 1
2017-08-15 17:30:04,500 - Thread-2 - DEBUG - 1
2017-08-15 17:30:04,500 - MainThread - DEBUG - Thread-2 is_alive: True join() activeCount: 3
2017-08-15 17:30:06,500 - Thread-3 - DEBUG - 1
2017-08-15 17:30:08,503 - MainThread - DEBUG - Thread-3 is_alive: True join() activeCount: 2
2017-08-15 17:30:12,500 - MainThread - DEBUG - MainThread End
python多线程之t.setDaemon(True) 和 t.join()的更多相关文章
- python多线程之threading模块
threading模块中的对象 其中除了Thread对象以外,还有许多跟同步相关的对象 threading模块支持守护线程的机制 Thread对象 直接调用法 import threading imp ...
- python多线程之Threading
什么是线程? 线程是操作系统内核调度的基本单位,一个进程中包含一个或多个线程,同一个进程内的多个线程资源共享,线程相比进程是“轻”量级的任务,内核进行调度时效率更高. 多线程有什么优势? 多线程可以实 ...
- python多线程之Event(事件)
#!/usr/bin/env python # -*- coding: utf-8 -*- import time from threading import Thread, Event import ...
- “死锁” 与 python多线程之threading模块下的锁机制
一:死锁 在死锁之前需要先了解的概念是“可抢占资源”与“不可抢占资源”[此处的资源可以是硬件设备也可以是一组信息],因为死锁是与不可抢占资源有关的. 可抢占资源:可以从拥有他的进程中抢占而不会发生副作 ...
- python多线程之Condition(条件变量)
#!/usr/bin/env python # -*- coding: utf-8 -*- from threading import Thread, Condition import time it ...
- python多线程之semaphore(信号量)
#!/usr/bin/env python # -*- coding: utf-8 -*- import threading import time import random semaphore = ...
- python多线程之threading、ThreadPoolExecutor.map
背景: 某个应用场景需要从数据库中取出几十万的数据时,需要对每个数据进行相应的操作.逐个数据处理过慢,于是考虑对数据进行分段线程处理: 方法一:使用threading模块 代码: # -*- codi ...
- python 线程之_thread
python 线程之_thread _thread module: 基本用法: def child(tid): print("hello from child",tid) _thr ...
- python 线程之 threading(四)
python 线程之 threading(三) http://www.cnblogs.com/someoneHan/p/6213100.html中对Event做了简单的介绍. 但是如果线程打算一遍一遍 ...
随机推荐
- ES--04
第三十一讲! 分布式文档系统 写一致性原理以及相关参数 课程大纲 (1)consistency,one(primary shard),all(all shard),quorum(default) 我们 ...
- Android App增量升级
移动互联网主打的就是用户体验和产品的快速迭代,通过用户反馈和用户行为跟踪及时调整产品方向,这样才能持续保持生命力和创造力.说的接地气点就是,你频繁的升级更新,有时只是修复了几个bug或者微调了下界面, ...
- Laravel 5.2数据库--迁移migration
Laravel中的migrations文件存放的是数据库表文件等结构,可以说是一个跟git差不多的,可以说像是数据库的版本控制器,所以可以叫做迁移.因为它可以很快速的很容易地构建应用的数据库表结构. ...
- 【原创】大数据基础之Flume(2)应用之kafka-kudu
应用一:kafka数据同步到kudu 1 准备kafka topic # bin/kafka-topics.sh --zookeeper $zk:2181/kafka -create --topic ...
- Java二叉树的实现与特点
二叉树是一种非常重要的数据结构,它同时具有数组和链表各自的特点:它可以像数组一样快速查找,也可以像链表一样快速添加.但是他也有自己的缺点:删除操作复杂. 我们先介绍一些关于二叉树的概念名词. 二叉树: ...
- 8 张图帮你一步步看清 async/await 和 promise 的执行顺序(转)
https://mp.weixin.qq.com/s?__biz=MzAxODE2MjM1MA==&mid=2651555491&idx=1&sn=73779f84c289d9 ...
- js——类型转换
总述 类型转换:显式.隐式(自动) 隐式转换是由编译器自动进行的,基本主要抽象操作有ToPrimitive, ToNumber, ToString, ToBoo ...
- 坚持:学习Java后台的第一阶段,我学习了那些知识
最近的计划是业余时间学习Java后台方面的知识,发现学习的过程中,要学的东西真多啊,让我一下子感觉很遥远.但是还好我制定了计划,自己选择的路,跪着也要走完!关于计划是<终于,我还是下决心学Jav ...
- oracle 在C# 中调用oracle的数据库时,出现引用库和当前客户端不兼容的问题解决方案
oracle 在C# 中调用oracle的数据库时,出现引用库和当前客户端不兼容的问题解决方案 解决方案 1.直接引用 Oracle.ManagedDataAccess.Client.dll动态库即 ...
- Ajax中onreadystatechange函数不执行,是因为放在open()后
今天动手写Ajax时遇到的问题:按照下面的顺序来写Ajax,功能是alert出txt文档的内容,在Chrome下可以执行onreadystatechange中的事件,在IE11及以下.FF就不能执行o ...