Demo 是最好的老师!!!

参考链接:Python多线程与多线程中join()的用法 - cnkai - 博客园

知识点一(setDaemon(False)):
当一个进程启动之后,会默认产生一个主线程,因为线程是程序执行流的最小单元,当设置多线程时,主线程会创建多个子线程,在 python 中,默认情况下(其实就是setDaemon(False)),主线程执行完自己的任务以后,此时子线程会继续执行自己的任务,直到自己的任务结束。

import threading
import timedef run():time.sleep(2)print('当前线程的名字是: ', threading.current_thread().name)time.sleep(2)if __name__ == '__main__':start_time = time.time()print('这是主线程:', threading.current_thread().name)thread_list = []for i in range(5):t = threading.Thread(target=run)thread_list.append(t)for t in thread_list:t.start()print('主线程结束!', threading.current_thread().name)print('一共用时:', time.time() - start_time)
这是主线程: MainThread
主线程结束! MainThread
一共用时: 0.001401662826538086
当前线程的名字是:  Thread-3
当前线程的名字是:  Thread-4
当前线程的名字是:  Thread-2
当前线程的名字是:  Thread-1
当前线程的名字是:  Thread-5Process finished with exit code 0

知识点二(setDaemon(True)):
当我们使用 setDaemon(True) 方法,设置子线程为守护线程时,主线程一旦执行结束,则全部线程全部被终止执行,可能出现的情况就是,子线程的任务还没有完全执行结束,就被迫停止。

import threading
import timedef run():time.sleep(2)print('当前线程的名字是: ', threading.current_thread().name)time.sleep(2)if __name__ == '__main__':start_time = time.time()print('这是主线程:', threading.current_thread().name)thread_list = []for i in range(5):t = threading.Thread(target=run)thread_list.append(t)for t in thread_list:t.setDaemon(True)t.start()print('主线程结束了!', threading.current_thread().name)print('一共用时:', time.time() - start_time)
这是主线程: MainThread
主线程结束了! MainThread
一共用时: 0.002007722854614258Process finished with exit code 0

知识点三(setDaemon(True) and join):
此时 join 的作用就凸显出来了,join 所完成的工作就是线程同步,即主线程任务结束之后,进入阻塞状态(并没有退出),会一直等待其他的子线程都执行结束之后,主线程再终止(退出)。所以多线程里边同时使用 join() 和 setDaemon() 是并不矛盾的。

import threading
import timedef run():time.sleep(2)print('当前线程的名字是: ', threading.current_thread().name)time.sleep(2)if __name__ == '__main__':start_time = time.time()print('这是主线程:', threading.current_thread().name)thread_list = []for i in range(5):t = threading.Thread(target=run)thread_list.append(t)for t in thread_list:t.setDaemon(True)t.start()for t in thread_list:t.join()print('主线程结束了!', threading.current_thread().name)print('一共用时:', time.time() - start_time)
这是主线程: MainThread
当前线程的名字是:  Thread-1
当前线程的名字是:  Thread-3
当前线程的名字是:  Thread-2
当前线程的名字是:  Thread-5
当前线程的名字是:  Thread-4
主线程结束了! MainThread
一共用时: 4.003052711486816Process finished with exit code 0

知识点四(join(timeout=param)):
join 有一个 timeout 参数:当设置守护线程时,含义是主线程对于子线程等待 timeout 的时间将会杀死该子线程,最后退出程序。所以说,如果有10个子线程,全部的等待时间就是每个 timeout 的累加和(10 * timeout)。简单的来说,就是给每个子线程一个 timeout 的时间,让他去执行,时间一到,不管任务有没有完成,直接杀死。

import threading
import timedef run():time.sleep(2)print('当前线程的名字是: ', threading.current_thread().name)time.sleep(2)if __name__ == '__main__':start_time = time.time()print('这是主线程:', threading.current_thread().name)thread_list = []for i in range(5):t = threading.Thread(target=run)thread_list.append(t)for t in thread_list:t.setDaemon(True)t.start()for t in thread_list:# 线程列表总共 5 个元素,所以主线程会在这儿等待 5 * 0.2 秒t.join(timeout=0.2)print('主线程结束了!', threading.current_thread().name)print('一共用时:', time.time() - start_time)
这是主线程: MainThread
主线程结束了! MainThread
一共用时: 1.0173823833465576Process finished with exit code 0

没有设置守护线程时,主线程将会等待 timeout 的累加和这样的一段时间,时间一到,主线程结束,但是并没有杀死子线程(设置守护的话才会去杀死子线程),子此时线程依然可以继续执行,直到子线程全部结束,程序退出。

最后来个自己实际项目中遇到的例子:

需求:已知有一个 src.rpm 的包,我只知道它和 conf.ini 中的地址拼接起来的 url 中,只有一个是有效的。如何快速把这个包下载下来?

conf.ini:

[centos]
src_package1=https://vault.centos.org/7.6.1810/centosplus/Source/SPackages/
src_package2=https://vault.centos.org/7.6.1810/cloud/Source/openstack-ocata/
src_package3=https://vault.centos.org/7.6.1810/cloud/Source/openstack-ocata/common/
src_package4=https://vault.centos.org/7.6.1810/cloud/Source/openstack-pike/
src_package5=https://vault.centos.org/7.6.1810/opstools/Source/common/
src_package6=https://vault.centos.org/7.6.1810/cloud/Source/openstack-queens/
src_package7=https://vault.centos.org/7.6.1810/cloud/Source/openstack-rocky/
src_package8=https://vault.centos.org/7.6.1810/cloud/Source/openstack-stein/
import configparser
import os
import threading
import timedef download(download_url):global is_downloadedwith pool_sema:status_code = os.system('wget -q %s' % download_url)if status_code == 0:# 如果已经成功下载,修改全局变量,方便主线程获取已下载信号后跳出循环,结束程序执行。is_downloaded = Trueif __name__ == '__main__':global is_downloadedis_downloaded = Falsesrc_package = 'centos-release-opstools-1-4.el7.src.rpm'conf = configparser.ConfigParser()conf.read('conf.ini', encoding="UTF-8")thread_list = []max_connections = 10  # 定义最大线程数pool_sema = threading.BoundedSemaphore(max_connections)t1 = time.perf_counter()for i in range(1, 9):url = conf.get('centos', 'src_package' + str(i))download_url = os.path.join(url, src_package)thread = threading.Thread(target=download, args=(download_url,))thread_list.append(thread)# 设置守护,也即主线程(main函数)结束的话(下载超时或者源码包已经成功下载),# 所有子线程必须强制退出(后面的download_url就不必再去尝试 wget 了)for t in thread_list:t.setDaemon(True)t.start()# 主线程不需要等待子线程全部结束后才退出,# 只需要获取到某个子线程已经成功下载的信号(is_downloaded)之后即可自行退出# for t in thread_list:#     t.join()while True:t2 = time.perf_counter()# 下载超时后跳出循环,结束执行if t2 - t1 > 5 * 10:print('download timeout')breakif is_downloaded:print('download success')breakt2 = time.perf_counter()print('download costs %.2f seconds' % (t2 - t1))
[root@localhost insight-tool]# python3 test.py
download success
download costs 4.35 seconds

Python 多线程中的 join() 和 setDaemon()相关推荐

  1. python threading中的join和setDaemon方法

    python 多线程的threading中的join和setDaemon方法 join():通俗的将就是阻止子线程随着主线程的结束而结束 setDaemon():设置子线程是否随着主线程的结束而结束, ...

  2. python 多线程中的 join 和 daemon

    文章目录 第一关:简单的 join() 第二关:join(timeout) 第三关:setDaemon(True) 第一关:简单的 join() import threading import tim ...

  3. python 多线程 setdaemon_Python线程join和setDaemon

    看一下线程的setDaemon()方法 importtimeimportthreadingimportctypesimportinspectdefsayHello():for i in range(1 ...

  4. Python多线程中阻塞(join)与锁(Lock)的使用误区

    参考资料:https://blog.csdn.net/cd_xuyue/article/details/52052893 1使用两个循环分别处理start和join函数.即可实现并发. threads ...

  5. java多线程中的join方法详解

    java多线程中的join方法详解 方法Join是干啥用的? 简单回答,同步,如何同步? 怎么实现的? 下面将逐个回答. 自从接触Java多线程,一直对Join理解不了.JDK是这样说的:join p ...

  6. python 多线程 setdaemon_彻底理解Python多线程中的setDaemon与join配有GIF示意

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

  7. python 多线程 setdaemon_彻底理解Python多线程中的setDaemon与join【配有GIF示意】

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

  8. python多线程中join()的理解

    在 Python 的多线程编程中,经常碰到 thread.join()这样的代码.那么今天咱们用实际代码来解释一下 join 函数的作用. 第一,当一个进程启动之后,会默认产生一个主线程,因为线程是程 ...

  9. 教你控制Python多线程中线程数量

    前言 前段时间学习了python的多线程爬虫,当时爬取一个图片网站,开启多线程后,并没有限制线程的数量,也就是说,如果下载1000张图片,会一次性开启1000个子线程同时进行下载 现在希望控制线程数量 ...

最新文章

  1. CacheHelper
  2. JavaScript 页面间传值
  3. 面试时候可以问的问题集锦
  4. rabbitmq 集群搭建
  5. 传递类型为参数的方法
  6. Java加载sklearn训练好的模型进行预测(无法搞定)
  7. Angular ActivatedRouteSnapshot
  8. php 修改文件属性命令行,Linux_linux中如何通过命令修改文件属性,ls -l即可查看目录信息-rw - phpStudy...
  9. tkinter的可视化拖拽工具_可视化越做越丑?这五个高级图表效果实现流程分享给你...
  10. Chapter 2 Open Book——5
  11. java配置struts2_[Java教程]struts2配置
  12. css 超出N行文本如何处理
  13. VUE下载文件并修改文件名
  14. 常微分方程机敏问答[1] #20210611
  15. python反爬虫与绕过_python中绕过反爬虫的方法总结
  16. 用计算机管理从新分区,电脑如何分区硬盘分区_电脑怎么重新分区教程-win7之家...
  17. NodeJs 畅谈异步
  18. directX 正试图在 OS 加载程序锁内执行托管代码
  19. visio2007或office 2007安装失败提示一个或多个受保护的windows文件导致office 2007安装失败
  20. python中repr的用法_python中repr函数作用是什么?

热门文章

  1. LabVIEW安装NI-DAQmx的方法(适合2021版和2022版)
  2. UE4喷气背包功能的实现--延续上篇自定义移动组件
  3. 震惊,程序员小编平时竟然上这种网站
  4. 负数 补码 原码
  5. 上架打包错误信息:Found an unexpected Mach-0 header code: 0x72613c21
  6. python对象数组排序_Python NumPy 数组 排序
  7. Hive TOP N 实现方法
  8. 简体繁体的转换,好难啊!(可怜白发生)
  9. mysql默认空列的弊端
  10. [附源码]java+ssm计算机毕业设计基于Web的操作系统题库平台06brw(源码+程序+数据库+部署)