线程与进程:

  • 线程对于进程来说,就好似工厂里的工人,分配资源是分配到工厂,工人再去处理。
  • 线程是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。
  • 在单个程序中同时运行多个线程完成不同的工作,称为多线程
  • 对于IO密集型的程序来说,多线程可以利用读IO的时间去做其他事【IO并不占用CPU,这就好像A买个一份外卖,他只需要等着送过来然后敲A家的门就行了】;
  • 而对于CPU密集型的程序来说,多线程的效率就不是很高了【CPU由于要计算,切换之间要恢复之前的现场消耗相对较大,比如我同时做几份作业,一份作业做十分钟,假如十分钟做不完一份作业,那么我后面再回头做的时候,我就要好好想想刚才做到哪,刚才想到哪】

    补充:IO需要CPU吗?知乎:https://www.zhihu.com/question/27734728


  • 线程Threading:

    python中多线程需要使用threading模块

    线程的创建与运行:

    1.直接调用threading的Thread类:

    线程的创建:线程对象=thread.Thread(target=函数名,args=(参数))【补充,由于args是一个元组,单个参数时要加“,”】

    线程的启动:线程对象.start(),调用start(),那么线程对象会自动去调用thread.Thread中的run()

    让主线程等待其余线程结束:线程对象.join(),加了join之后,相当于阻塞了主线程,主线程只有当join的线程结束后才会向下执行

    import threading,time
    
    def run(n):
    time.sleep(1)
    print("task ",n) t1=threading.Thread(target=run,args=("t1",))
    t2 = threading.Thread(target=run,args=("t2",)) start_time=time.time()#开始时间
    t1.start()
    t2.start()
    ##因为是独立线程,如果想要主线程等待其他线程运行完毕,需要使用join
    t1.join()
    t2.join()
    spend_time=time.time()-start_time
    print(spend_time)##1.0多,说明是并行的结果

    附加说明--join是阻塞等待:

    import threading,time
    
    class MyTread(threading.Thread):
    def __init__(self,name):
    super(MyTread,self).__init__()#调用父类的__init__()
    self.name=name
    def run(self):#重写方法,按自己的要求去写
    time.sleep(1)
    print("run in task",self.name,threading.current_thread(),threading.active_count()) t1=MyTread("t1")
    t2=MyTread("t2")
    start_time=time.time()
    t1.start()
    t2.start() t1.join()
    t2.join()
    time.sleep(1)###主线程等待其余线程结束
    print(time.time()-start_time)
    #结果是2.0多,证明是join是相当于阻塞了主线程的执行,只有当线程结束后才会向下执行

    2.继承threading的Thread类:

    继承threading的Thread类的类要主要做两件事:

    1.如果不做自定义变量的初始化,那么可以直接使用继承的父类的__init__(),如果需要做自定义变量的初始化,则需要先调用父类的__init__()【否则需要自己填写线程初始化相关的参数】

  • 2.重写run,虽然继承了父类的run,但实际上如果不重写,那么我们继承threading的Thread类又有什么意义呢?为什么不直接调用threading的Thread类

  • import threading,time
    
    class MyTread(threading.Thread):
    def __init__(self,name):
    super(MyTread,self).__init__()#调用父类的__init__()
    self.name=name
    def run(self):#重写方法,按自己的要求去写
    time.sleep(1)
    print("run in task",self.name,threading.current_thread(),threading.active_count()) t1=MyTread("t1")
    t2=MyTread("t2")
    start_time=time.time()
    t1.start()
    t2.start()
    ###主线程等待其余线程结束
    t1.join()
    t2.join()
    print(time.time()-start_time)#结果是1.0多,证明是并行的

    子线程:

    • 由一个线程启动的线程可以成为它的子线程,A启动B,B是A的子线程,A是B的父线程


    线程的几个常用函数:

    • threading.current_thread():
    返回当前正在运行的线程对象
     
    • threading.active_count():
    返回当前进程中的存活的线程对象数

    • 线程对象.isAlive()方法判断线程是否存活

    • getName(): 返回线程名。

    • setName(): 设置线程名。

  • get_ident():获取当前线程ID。


    守护线程:

    • 守护线程是起到辅助功能的,就好像魔法师放禁咒总要骑士保护一样【魔法师只需要关系自己的任务,保护他的任务交给守护者】

    • 而守护线程与主线程的关系呢,就好像备胎跟女神,去买东西的话,备胎要一直在外面等女神【守护线程运行结束就狗带,但不影响主进程结束,由主线程决定运行时间】,女神不需要等待备胎【主线程结束,守护线程也要结束,不管自身任务是否完成】
    • 与join的区别:join是阻塞等待,守护线程是并行的等待
    • 设置守护线程:线程对象.setDaemon(True)【注意!!!!!设置守护线程必须要在start()前面,不然会报错】

    下面的代码显示了主线程并不会等待其守护线程结束:

    import threading,time
    
    class MyTread(threading.Thread):
    
        def __init__(self,name):
    super(MyTread,self).__init__()
    self.name=name
    def run(self):
    print("守护线程已经启动",self.name)
    time.sleep(1)
    print("run in task",self.name,threading.current_thread(),threading.active_count()) t1=MyTread("t1")
    t1.setDaemon(True)
    t2=MyTread("t2")
    t2.setDaemon(True)
    start_time=time.time()#开始时间
    t1.start()
    t2.start() spend_time=time.time()-start_time
    print(spend_time)##0.0多,而且三个线程都执行完毕了,说明这个是并行的等待

    让主线程sleep一下,显示一下如果主线程要等待守护线程,那么是并行的等待:

    import threading,time
    
    class MyTread(threading.Thread):
    
        def __init__(self,name):
    super(MyTread,self).__init__()
    self.name=name
    def run(self):
    print("守护线程已经启动",self.name)
    time.sleep(1)
    print("run in task",self.name,threading.current_thread(),threading.active_count()) t1=MyTread("t1")
    t1.setDaemon(True)
    t2=MyTread("t2")
    t2.setDaemon(True)
    start_time=time.time()#开始时间
    t1.start()
    t2.start()
    time.sleep(2)
    spend_time=time.time()-start_time
    print(spend_time)##2.0多,而且三个线程都执行完毕了,说明这个是并行的等待


  • 12、多线程:Threading、守护线程的更多相关文章

    1. Java多线程之守护线程

      Java多线程之守护线程 一.前言 Java线程有两类: 用户线程:运行在前台,执行具体的任务,程序的主线程,连接网络的子线程等都是用户线程 守护线程:运行在后台,为其他前台线程服务 特点:一旦所有用 ...

    2. 【python】-- 继承式多线程、守护线程

      继承式多线程 1.定义 继承式多线程是自己自定义类,去继承theading.Tread这个类,通过类实例.start()启动,去执行run方法中的代码. import threading import ...

    3. 20190102(多线程,守护线程,线程互斥锁,信号量,JoinableQueue)

      多线程 多进程: 核心是多道技术,本质上就是切换加保存技术. 当进程IO操作较多,可以提高程序效率. 每个进程都默认有一条主线程. 多线程: 程序的执行线路,相当于一条流水线,其包含了程序的具体执行步 ...

    4. [javaSE] 多线程(守护线程)

      我们一般使用多线程,都是while的死循环,想要结束线程,只需退出死循环即可 当线程中调用了sleep()方法或者wait()方法,当前的线程就会进入冻结状态,这个线程就结束不了 调用Thread对象 ...

    5. python中多进程multiprocessing、多线程threading、线程池threadpool

      浅显点理解:进程就是一个程序,里面的线程就是用来干活的,,,进程大,线程小 一.多线程threading 简单的单线程和多线程运行:一个参数时,后面要加逗号 步骤:for循环,相当于多个线程——t=t ...

    6. 【多线程】守护线程 Daemon

      守护线程 Daemon 线程分为用户线程和守护线程 虚拟机必须确保用户线程执行完毕 虚拟机不用等待守护线程执行完毕 如,后台记录操作日志,监控内存,垃圾回收等待.. 代码示例: /** * @Desc ...

    7. java 22 - 12 多线程之解决线程安全问题的实现方式1

      从上一章知道了多线程存在着线程安全问题,那么,如何解决线程安全问题呢? 导致出现问题的原因: A:是否是多线程环境 B:是否有共享数据 C:是否有多条语句操作共享数据 上一章的程序,上面那3条都具备, ...

    8. java多线程之守护线程以及Join方法

      版权声明:本文出自汪磊的博客,转载请务必注明出处. 一.守护线程概述及示例 守护线程就是为其它线程提供"守护"作用,说白了就是为其它线程服务的,比如GC线程. java程序中线程分 ...

    9. java多线程之守护线程与非守护线程

      在java线程中有两种线程,一种是用户线程,其余一种是守护线程. 守护线程具有特殊的含义,比如gc线程.当最后一个非守护线程执行完后,守护线程随着jvm一同结束工作. java中的守护线程需要将Dae ...

    10. python的多线程和守护线程

      1.创建一个多线程 import threading import time ''' def threading_func(num): print("running on number:%s ...

    随机推荐

    1. C语言中volatile的作用和使用方法

      在程序设计中,尤其是在C语言.C++.C#和Java语言中,使用volatile关键字声明的变量或对象通常具有与优化.多线程相关的特殊属性. 通常,volatile关键字用来阻止(伪)编译器认为的无法 ...

    2. (转)内核模块操作命令-lsmod+rmmod+modinfo+modprobe

      原文:http://watchmen.xin/2018/07/13/IT%E7%A7%91%E5%AD%A6%E6%8A%80%E6%9C%AF%E7%9F%A5%E8%AF%86%E4%BD%93% ...

    3. 程序员、互联网从业者必读KK三大力作之《必然》总结

    4. JVM-常用内存调优参数总结

      一.内存调整参数 -Xmx2g    设置堆内存最大值为2g -Xmx512m  设置堆内存最大值为512m -Xms1g   设置堆内存最小值1g (ps:-Xms和-Xmx实际上是 -XX:Ini ...

    5. C# 动态生成类 枚举等

      private void GenerateCode() { /*注意,先导入下面的命名空间 using System.CodeDom using System.CodeDom.Compiler; us ...

    6. Spring Boot+redis存储session,满足集群部署、分布式系统的session共享

      本文讲述spring-boot工程中使用spring-session机制进行安全认证,并且通过redis存储session,满足集群部署.分布式系统的session共享. 原文链接:https://w ...

    7. GO入门——7. 并发

      1 并发 1.1 goroutine Goroutine 奉行通过通信来共享内存,而不是共享内存来通信 goroutine 只是由官方实现的超级"线程池"而已. 每个实例 4-5K ...

    8. c time类型详解

      linux下存储时间常见的有两种存储方式,一个是从1970年01月01日 0:00:00到现在经过了多少秒,一个是用一个结构来分别存储年月日时分秒的.time_t 这种类型就是用来存储从1970年到现 ...

    9. RestTemplate发送HTTP、HTTPS请求

      RestTemplate 使用总结   场景: 认证服务器需要有个 http client 把前端发来的请求转发到 backend service, 然后把 backend service 的结果再返 ...

    10. [转]Angular 2 / 4 / 5 not working in IE11

      本文转自:https://stackoverflow.com/questions/35140718/angular-2-4-5-not-working-in-ie11/47777695#4777769 ...