• 线程与守护线程


    线程

    1,生产者消费者模型

    1. 什么是生产者与消费者模型
      • 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题,生产者和消费者之间不直接通讯,而通过阻塞队列来通讯,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力
      • 在并发编程中使用生产者和消费者模式能够解决大多数并发问题,该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度
    2. 基于队列(容器)实现生产者和消费者模型

    2,线程

    1. 定义
      • 进程是一个资源单位,线程是CPU上的执行单位
      • 一个进程里面开多个线程,共享一个进程里面的内存空间数据

    3,开启线程的两种方式

    1. 进程的开启必须是在main下开启,但是线程的开启不是一定在main下开启

    2. 第一种:在main下开启,和进程的开启方式一样

      1. 1 1.创建线程的开销比创建进程的开销小,因而创建线程的速度快
        2 from multiprocessing import Process
        3 from threading import Thread
        4 import os
        5 import time
        6 def work():
        7     print('<%s> is running'%os.getpid())
        8     time.sleep(2)
        9     print('<%s> is done'%os.getpid())
        11 if __name__ == '__main__':
        12     t=Thread(target=work,)
        14     t.start()
        15     print('主',os.getpid())
        
    3. 第二种:继承与Thread类方式的开启

      1. 1 from threading import Thread
        2 import time
        3 class Work(Thread):
        4     def __init__(self,name):
        5         super().__init__()
        6         self.name = name
        7     def run(self):
        8         # time.sleep(2)
        9         print('%s say hell'%self.name)
        10 if __name__ == '__main__':
        11     t = Work('egon')
        12     t.start()
        13     print('主')
        

    线程vs进程的对比

    1. 开启一个进程,会在内存中开辟一个口进程空间,将主进程的数据全部复制一份,通过线程执行代码
    2. 创建线程的开销比进程小,创建进程需要开空间,而线程存在于进程里面,线程不需要开空间
    3. 同一个进程内的多线程之间可以共享数据,进程与进程之间是相互空间隔离的,需借助队列的方法实现通行
    4. 同一个进程下开多个子进程的pid是不同的,但是开多个线程的pid是相同的

    线程的相关其他方法

    1. Thread实例对象方法

      • isAlive() :返回线程是否是活动的
      • getName():返回线程名
      • setName():设置线程名
    2. threading模块提供的一些方法

      • threading.currentThread():返回当前的线程变量
      • Threadind.enumerate(): 返回一个正在运行的线程的list
      • threading.activeCount():返回正在运行的线程数量,与len(Threadind.enumerate())有相同的效果
    3. 其他属性

      • 1 from  threading import Thread
         2 from multiprocessing import Process
         3 import time,os,threading
         4 def work():
         5     time.sleep(2)
         6     print('%s is running' % threading.currentThread().getName())
         7     print(threading.current_thread()) #其他线程
         8     print(threading.currentThread().getName()) #得到其他线程的名字
         9 if __name__ == '__main__':
        10     t = Thread(target=work)
        11     t.start()
        12 
        13     print(threading.current_thread().getName())  #主线程的名字
        14     print(threading.current_thread()) #主线程
        15     print(threading.enumerate()) #连同主线程在内有两个运行的线程
        16     time.sleep(2)
        17     print(t.is_alive()) #判断线程是否存活
        18     print(threading.activeCount())
        19     print('主')
        
        

    守护线程

    1. join与守护线程

      • 主进程等所有的非守护的子进程结束他才结束(回收他的字进程资源):有父子关系
      • 主线程等非守护线程全部结束它才结束:没 父子关系
    2. 守护线程与守护进程的区别

      • 守护进程:主进程会等到所有的非守护进程结束,守护进程随着主进程的结束也结束
      • 守护线程:主线程等到非守护线程全部结束才结束,
    3. 实例

      • from  multiprocessing import Process
        from threading import Thread,currentThread
        import time,os
        def talk1():
            time.sleep(2)
            print('hello')
        def talk2():
            time.sleep(2)
            print('you see see')
        if __name__ == '__main__':
            t1 = Thread(target=talk1)
            t2 = Thread(target=talk2)
            # t1 = Process(target=talk1)
            # t2 = Process(target=talk2)
            t1.daemon = True
            t1.start()
            t2.start()
            print('主线程',os.getpid())
        ########################################
        主线程 11288
        you see see
        hello
        ###############或者##################3
        主线程 5664
        hello
        you see see
        
      • #3 --------迷惑人的例子
        from threading import Thread
        import time
        def foo():
            print(123)
            # time.sleep(10) #如果这个等的时间大于下面等的时间,就把不打印end123了
            time.sleep(2)  #如果这个等的时间小于等于下面等的时间,就把end123也打印了
            print('end123')
        def bar():
            print(456)
            # time.sleep(5)
            time.sleep(10)
            print('end456')
        if __name__ == '__main__':
            t1 = Thread(target=foo)
            t2 = Thread(target=bar)
            t1.daemon = True #主线程运行完了守护的那个还没有干掉,
            # 主线程等非守护线程全都结束它才结束
            t1.start()
            t2.start()
            print('main---------')
        #############大于##################
        123
        456
        main---------
        end456
        ##############小于等于#############
        123
        456
        main---------
        end123
        end456
        
    希望你眼眸有星辰,心中有山海,从此以梦为马,不负韶华
  • 相关阅读:
    音频电路设计中的基本知识(-)
    Usart的单线半双工模式(stm32F10x系列)
    RTS与CTS的含义
    NetBIOS与Winsock编程接口
    debian下使用gitosis+gitweb搭建SSH认证的git服务器
    解决:无法将“Add-Migration”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次
    Windows Azure Storage Client Library 2.0 入门
    Windows Azure Table Storage 解决 Guid 查询问题
    EF 报【序列包含一个以上的元素】解决办法
    javascript技巧大全套
  • 原文地址:https://www.cnblogs.com/daviddd/p/12034410.html
Copyright © 2020-2023  润新知