• 线程基础和用法


    一、线程

    1. 初识线程
      在传统操作系统种,每个进程有一个地址空间,而且默认就有一个控制线程,cpu真正的执行单位是线程。
      在工厂中,每一个车间都有房子,而且每个车间默认就有一个流水线。

    2. 做一个比较

      ​ 相当于
      操作系统------->工厂
      进程------->车间
      线程------->流水线
      cpu------->电源

    3. 线程:cpu最小的执行单位
      进程:资源集合/资源单位
      线程运行 ------->代码运行
      进程运行------->各种资源 + 线程

    4. 右键运行会发生的事情:申请内存空间,先将解释器代码丢进去并且把python代码丢进去(进程做的)(内存运行的时候不识别python文件代码,只有解释器才能识别python文件代码,所有先把解释器放入内存),运行代码(线程)

    5. 进程和线程的区别:
      过程描述的区别
      线程------->单指代码的执行过程
      进程------->资源的申请与销毁的过程

    6. 进程内存空间彼此隔离(内存共享or隔离

      多个进程内存空间彼此隔离。

      同一进程下的多个线程共享该进程内的数据。同一个进程下的线程共享资源

    7. 进程和线程的创造速度
      进程需要申请资源开辟空间------->慢
      只是告诉操作系统一个执行方案------->快

    8. 1 进程的启动和销毁(空间开始和释放)

      只要一说一个进程启动了,那你知道了一个事情,是关于这个程序的一块空间造好了。

      只要一说进程销毁了,那你也知道了一个事情,是关于这个程序的空间释放了。

      2 线程的启动和销毁(进程里的一段代码运行起来了,进程里的一段代码运行结束)

    9. 进程之间是竞争关系,线程之间是协作关系?(了解)

      车间直接是竞争/抢电源的关系,竞争(不同的进程直接是竞争关系,是不同的程序员写的程序运行的,迅雷抢占其他进程的网速,360把其他进程当做病毒干死)
      一个车间的不同流水线式协同工作的关系(同一个进程的线程之间是合作关系,是同一个程序写的程序内开启动,迅雷内的线程是合作关系,不会自己干自己)

    二、开启线程的俩种方式

    由于线程开启不会出现一直循环调用开启的情况和进程是不同的,所以不需要用main来隔绝,但可以使用。

    2.1方式1

    from threading import Thread
    import time
    def task():
        print('线程 start')
        time.sleep(2)
        print('线程end')
    if __name__ == '__main__':
        t = Thread(target=task)
        t.start()
        print('主进程')
    ################
    线程 start
    主进程
    线程end
    

    2.2方式2

    from threading import Thread
    import time
    class Myt(Thread):
        def run(self):
            print('子进程 start')
            time.sleep(2)
            print('子进程 end')
    t = Myt()
    t.start()
    print('主')
    #######################
    子进程 start
    主
    子进程 end
    
    

    三、子进程vs子线程创建速度

    from threading import Thread
    from multiprocessing import Process
    import time
    
    
    def task(name):
        print(f'{name} is runing')
        time.sleep(2)
        print(f'{name} is endding')
    
    
    if __name__ == '__main__':
        t= Thread(target=task,args=('子线程',))
        p = Process(target=task,args=('子进程',))
        t.start()
        p.start()
        print('主')
    ##########################
    子线程 is runing
    主
    子进程 is runing
    子线程 is endding
    子进程 is endding
    
    from threading import Thread
    from multiprocessing import Process
    import time
    
    
    def task(name):
        print(f'{name} is runing')
        time.sleep(2)
        print(f'{name} is endding')
    
    
    if __name__ == '__main__':
        t= Thread(target=task,args=('子线程',))
        # p = Process(target=task,args=('子进程',))
        t.start()
        # p.start()
        print('主')
    #######################
    子线程 is runing
    主
    子线程 is endding
    
    from threading import Thread
    from multiprocessing import Process
    import time
    
    
    def task(name):
        print(f'{name} is runing')
        time.sleep(2)
        print(f'{name} is endding')
    
    
    if __name__ == '__main__':
        # t= Thread(target=task,args=('子线程',))
        p = Process(target=task,args=('子进程',))
        # t.start()
        p.start()
        print('主')
    ##################
    主
    子进程 is runing
    子进程 is endding
    

    四、子线程共享资源

    from threading import Thread
    import time,os
    x = 100
    def task():
        global x
        x = 50
        print(os.getpid())
    if __name__ == '__main__':
        t = Thread(target=task)
        t.start()
        time.sleep(2)
        print(x)
        print(os.getpid())#处于一个进程,所以pid是一样的
    ###########
    16656
    50
    16656
    
    

    五、线程的jion方法

    5.1方法1

    
    from threading import Thread
    import time
    def task():
        print('子线程 start')
        time.sleep(2)
        print('子线程 end')
    t = Thread(target=task)
    t.start()
    t.join()#等待子线程运行结束
    print('主线程')
    ################
    子线程 start
    子线程 end
    主线程
    

    思考主线程是否会等子线程运行结束

    1 其实是进程在等
    貌似是主线程在原地等着,主线程已经运行完。
    原来没有子线程的情况下,其实就一个主线程这一条流水线工作完了,这个进程就结束了。
    那现在的情况是当前进程有其他的子线程,是进程等待自己所有的子线程运行完。
    
    # 主进程等子进程是因为主进程要给子进程收尸
    # 现在看到的等是进程必须等待其内部所有线程都运行完毕才结束。
    

    5.2方法2

    from threading import Thread
    import time
    def task(name,n):
        print(f'{name} start')
        time.sleep(n)
        print(f'{name} end')
    t1 = Thread(target=task,args=('线程1',1))
    t2 = Thread(target=task,args=('线程2',2))
    t3 = Thread(target=task,args=('线程3',3))
    start = time.time()
    t1.start()
    t2.start()
    t3.start()
    t1.join()
    t2.join()
    t3.join()
    end = time.time()
    print(end-start)
    ##########################
    线程1 start
    线程2 start
    线程3 start
    线程1 end
    线程2 end
    线程3 end
    3.0029337406158447
    
    

    5.3了解进程的jion

    from multiprocessing import Process
    from threading import Thread
    
    import time
    def task():
        print('进程 start')
        time.sleep(10)
        print('进程  end')
    def task2():
        print('子线程 start')
        time.sleep(3)
        print('子线程 end')
    if __name__ == '__main__':
        p = Process(target=task)
        t = Thread(target=task2)
        t.start()
        p.start()
        print('子进程的join开始')
        p.join()#主进程的主线程等待子进程运行结束
        print('主')
    ##################
    子线程 start
    子进程的join开始
    进程 start
    子线程 end
    进程  end
    主
    
    

    六、守护线程

    # 守护线程首先是一个线程。
        # 守护线程守护到当前进程运行结束。
        # ps:比如有未完成的子进程阶段会守护,比如有未完成的其他子线程也均会守护。
    # 守护进程首先是一个进程。
        # 守护进程守护到当前进程的最后一行代码结束。
    
    
    from threading import Thread,enumerate,currentThread
    import time
    def task():
        print('守护线程开始')
        print(currentThread())
        time.sleep(10)
        print('守护线程end')
    def task2():
        print('子线程 start')
        time.sleep(5)
        print(enumerate())
        print('子线程 end')
    if __name__ == '__main__':
        t1 = Thread(target=task)
        t2 = Thread(target=task2)
        t1.daemon = True
        t2.start()
        t1.start()
        print('主')
    ####################
    子线程 start
    守护线程开始
    <Thread(Thread-1, started daemon 13904)>
    主
    [<_MainThread(MainThread, stopped 13828)>, <Thread(Thread-2, started 3316)>, <Thread(Thread-1, started daemon 13904)>]
    子线程 end
    
    

    七、线程其他的相关用法

    Thread实例对象的方法

    1. isAlive(): 返回线程是否活动的。
    2. getName(): 返回线程名。
    3. setName(): 设置线程名。

    threading模块提供的一些方法:

    1. threading.currentThread(): 返回当前的线程变量。
    2. threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
    3. threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果
    • isalive()

      from threading import Thread,currentThread,enumerate,activeCount
      import time
      def task():
          print('子线程 start')
          time.sleep(2)
          print('子线程  end')
      if __name__ == '__main__':
          t1 = Thread(target=task)
          t2 = Thread(target=task)
          t1.start()
          t2.start()
         
          
          print(t1.is_alive())#子线程存在,True
      #################
      子线程 start
      子线程 start
      True
      子线程  end
      子线程  end
      
      
      
    • getname()

      from threading import Thread,currentThread,enumerate,activeCount
      import time
      def task():
          print('子线程 start')
          time.sleep(2)
          print('子线程  end')
      if __name__ == '__main__':
          t1 = Thread(target=task)
          t1.start()
      
          
          print(t1.getName())
          
      ##########################
      子线程 start
      Thread-1
      子线程  end
      
      
      
    • setname()

      from threading import Thread,currentThread,enumerate,activeCount
      import time
      def task():
          print('子线程 start')
          time.sleep(2)
          print('子线程  end')
      if __name__ == '__main__':
          t1 = Thread(target=task)
          t1.start()
      
          t1.setName('线程1')
          print(t1.getName())
      #####################
      子线程 start
      线程1
      子线程  end
      
      
    • currentTread()

      
      
    • enumerate()

      from threading import Thread,currentThread,enumerate,activeCount
      import time
      def task():
          print('子线程 start')
          time.sleep(2)
          print('子线程  end')
          print(enumerate())
      if __name__ == '__main__':
          t1 = Thread(target=task)
          t2 = Thread(target=task)
          t1.start()
          t2.start()
      ###################################
      子线程 start
      子线程 start
      子线程  end
      [<_MainThread(MainThread, stopped 12328)>, <Thread(Thread-1, started 6176)>, <Thread(Thread-2, started 14452)>]
      子线程  end
      [<_MainThread(MainThread, stopped 12328)>, <Thread(Thread-2, started 14452)>]
      
      
      from threading import Thread,currentThread,enumerate,activeCount
      import time
      def task():
          print('子线程 start')
          time.sleep(2)
          print('子线程  end')
      if __name__ == '__main__':
          t1 = Thread(target=task)
          t2 = Thread(target=task)
          t1.start()
          t2.start()
          print(enumerate())
      ########################
      子线程 start
      子线程 start
      [<_MainThread(MainThread, started 16964)>, <Thread(Thread-1, started 15796)>, <Thread(Thread-2, started 15476)>]
      子线程  end
      子线程  end
      
      
    • activeCount()与len(enumerate())

      from threading import Thread,currentThread,enumerate,activeCount
      import time
      def task():
          print('子线程 start')
          time.sleep(2)
          print('子线程  end')
      if __name__ == '__main__':
          t1 = Thread(target=task)
          t2 = Thread(target=task)
          t1.start()
          t2.start()
          print(activeCount())
          print(len(enumerate()))
      #################
      子线程 start
      子线程 start
      3
      3
      子线程  end
      子线程  end
      
      
    • 1

      from threading import Thread,currentThread,enumerate,activeCount
      import time
      def task():
          print('子线程 start')
          time.sleep(2)
          print('子线程  end')
      if __name__ == '__main__':
          t1 = Thread(target=task)
          t2 = Thread(target=task)
          t1.start()
          t2.start()
          print(currentThread())
          print(currentThread().name)
      ##################
      子线程 start
      子线程 start
      <_MainThread(MainThread, started 2696)>
      MainThread
      子线程  end
      子线程  end
      
      
      
  • 相关阅读:
    使用Stream方式处理集合元素
    Consumer方法结合Lambda表达式的应用
    java-遍历字符串的两种方式:1.char charAt(int index);2.char[] toCharArray()
    java-成员变量与局部变量的测试
    java-统计字符串中各字符次数
    java-字符串的遍历和字符串数组的遍历
    java-String类的获取方法(indexOf();substring()等)
    java-模拟登陆练习
    java-String类中的各字符串判断(包括" "和null的区别)
    java-String类的常见面试题
  • 原文地址:https://www.cnblogs.com/SkyOceanchen/p/11537610.html
Copyright © 2020-2023  润新知