zoukankan      html  css  js  c++  java
  • 什么是多线程?

    一、线程

    1.什么是线程

    ​ 回顾进程是操作系统可以调度已经进行资源分配的基本单位,是一个资源单位,其中包含了运行这个程序所需的资源 线程是操作系统可以运算调度的最小单位,是真正的执行单位,其包含在进程中, 一个线程就是一条固定的控制流程,

    一个进程可以包含多个线程,同一进程中的线程共享进程内的资源

    2、进程的特点

    系统会为每一个进程自动创建一条线程,称之为主线程, 后续通过代码开启的线程称之为子线程

    3、进程对比线程

    1)进程是一个资源单位,先是执行单位     
    
    2)创建进程的开销远大于线程     
    
    3)多个进程之间内存是相互隔离的   而线程是共享进程内的所有资源   
    
    4)进程之间之间对于硬件资源是竞争关系,而线程是协作关系  
    
    5)开启线程也是需要消耗资源的
    
    6)进程之间有层级关系 ,而线程之间没有是平等的  
    
    7)比喻: 
    
    ​	计算机是工厂     进程是车间     线程是流水线   
    

    为什么用线程

    1.有多个任务要并发处理

    2.当要并发处理的任务有很多的时,不能使用进程 进程资源开销太大 线程开销非常小 适用于任务数非常多的情况

    4、使用线程的两种方式

    方式1 直接实例化Thread类

    from threading  import Thread
    
    # def task():
    #     print("子线程 run")
    #
    # # 与进程不同之处1   不需要加判断 开启线程的代码放哪里都可以
    # t = Thread(target=task)
    # t.start()
    # print("over")
    
    
    # 使用方法2  继承Thread类
    class MyThread(Thread):
    
        def run(self):
            # 把要在子线中执行的代码放入run中
            print("子 run")
    
    mt = MyThread()
    mt.start()
    print("over")
    

    二、线程安全问题

    只要并发访问了同一资源一定会产生安全问题 ,解决方案和多进程一致 就是给操作公共资源代码加锁

    from threading import  Thread,Lock
    import time
    a = 10
    
    l = Lock()
    
    def task():
        global a
        l.acquire()
        temp = a
        time.sleep(0.1)
        a = temp - 1
        l.release()
    
    ts = []
    for i in range(10):
        t = Thread(target=task)
        t.start()
        ts.append(t)
    for t in ts:t.join()
    
    print(a)
    

    三、守护线程

    一个线程a 设置为b的守护线程, a会随着b的结束而结束

    默认情况下 主线程即使代码执行完毕 也会等待所有非守护线程完毕后程序才能结束 因为多个线程之间是协作关系

    from threading import Thread
    import time
    
    
    # 妃子的一生
    def task():
        print("妃子 start")
        time.sleep(5)
        print("妃子 over")
    
    def task2():
        print("皇太后 start")
        time.sleep(3)
        print("皇太后 over")
    
    
    # 皇帝的一生
    print("主 start")
    
    t = Thread(target=task)
    t.daemon = True
    t.start()
    
    t2 = Thread(target=task2)
    t2.start()
    
    print("主 over")
    
    
    """结果
    主 start 
    妃子start 
    皇太后 start 
    主over 
    皇太后 over
    
    """
    

    四、线程中的常用属性和方法

    from threading import  Thread,currentThread,enumerate,activeCount
    import time
    
    # t = Thread()
    # t.start()
    # t.join()
    # t.is_alive()
    # t.isAlive()
    # t.ident  # 线程标识符   id
    # t.daemon
    
    # 获取当前线程对象
    # print(currentThread())
    # t = Thread(target=lambda :print(currentThread()))
    # t.start()
    
    t = Thread(target=lambda :time.sleep(1))
    t.start()
    
    t = Thread(target=lambda :time.sleep(1))
    t.start()
    t.join()
    # 获取正在运行的所有线程对象  是一个列表
    print(enumerate())
    
    # 存活的线程数量
    print(activeCount())
    
  • 相关阅读:
    Bonding
    负载均衡
    XML
    wireshark
    IE
    轨迹系列7——Socket总结及实现基于TCP或UDP的809协议方法
    轨迹系列6——车载GPS对接方案汇总小结(809、自定义协议、前置库、WS)
    基于R树索引的点面关系判断以及效率优化统计
    WebGIS中以version方式实现代码更新后前端自动读取更新代码的方法
    轨迹系列5——验证轨迹GPS坐标转换为本地坐标的四/七参数是否准确的一种方案
  • 原文地址:https://www.cnblogs.com/chuwanliu/p/11134439.html
Copyright © 2011-2022 走看看