zoukankan      html  css  js  c++  java
  • 并发编程--多线程

    多线程

    什么是线程

    进程是操作系统可以调度已经进行资源分配的基本单位,是一个资源单位,其中包含了运行这个程序所需的资源

    • 线程是操作系统可以运算调度的最小单位,是真正的执行单位,其包含在进程中, 一个线程就是一条固定的控制流程, 一个进程可以包含多个线程,同一进程中的线程共享进程内的资源

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

    进程和线程的对比

    计算机是一个工厂,进程就是一个车间,线程就是车间内的流水线

    Item 进程 线程
    单位 资源单位 执行单位
    创建开销 开销大 开销小
    内存关系 内存相互隔离 共享进程内的所有资源
    硬件资源 竞争关系 协作关系
    层级关系 又上下层关系 平等关系

    使用线程的优势

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

    线程的使用

    1. 方式一:直接实例化Thread类

      from threading  import Thread
      
      
      def task():
          print("子线程 run")
      
      # 与进程不同之处1   不需要加判断 开启线程的代码放哪里都可以
      t = Thread(target=task)
      t.start()
      print("over")
      
    2. 方式二:继承Thread类,覆盖run方法

      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())
    
  • 相关阅读:
    阿里云服务器购买后的配置指南
    第一阶段总结
    RDD的checkpoint机制和键值对RDD数据分区
    广播变量与累加器
    Spark的监控
    Spark和MR的区别
    hadoop离线项目处理流程
    Flume(一)
    Sparkcore高级应用3
    SparkCore高级应用2(Spark on yarn)
  • 原文地址:https://www.cnblogs.com/Hades123/p/11153637.html
Copyright © 2011-2022 走看看