zoukankan      html  css  js  c++  java
  • Python----线程1

    1.线程的理论知识

    1. 什么是线程

      线程就是一条流水线.

      什么是进程? 进程开启经历了什么?

      开启进程: 内存中开空间,加载资源与数据,调用cpu执行,可能还会使用这个空间的资源.

      进程: 主要任务:,开启空间,加载数据.

      线程: 流水线,执行代码.

    1563953708745

    进程: 划分空间,加载资源. 静态的.

    线程: 执行代码.执行能力,动态的.

    抽象的概念.

    开启qq: 开启一个进程: 在内存中,开空间,加载数据. 启动一个线程执行代码.

    线程是依赖于进程, 一个进程可以包含多个线程.但是一定有一个主线程. 线程才是cpu执行的最小单元.

    1. 线程vs进程(理论)

      1. 开启多进程开销非常大. 10~100.开启线程开销非常小.

      2. 开启多进程的速度慢,开启多线程速度快.

      3. 进程之间数据不能直接共享通过队列可以.同一个进程下的线程之间的数据可以共享.

    2. 多线程的应用场景介绍

      并发: 一个cpu来回切换(线程之间的切换). 多进程并发, 多线程的并发.

      多进程并发: 开启多个进程, 每个进程里面的主线程执行任务.

      多线程并发: 开启1个进程, 此进程里面多个线程执行任务.

      什么时候用多进程,什么时候用多线程?

      一个程序: 三个不同的任务.

      如果以后工作中遇到并发:多线程居多.

    2.开启线程的两种方式

    # 第一种方式
    from threading import Thread
    def task(name):
         print(f'{name} is running')
    if __name__ == '__main__':
        t = Thread(target=task,args=('mcsaoQ',))
        t.start()
        print('主线程')
    #第二种方式
    from threading import Thread
    class MyThread(Thread):
        def run(self):
            print(f'{self.name} is running')
    if __name__ == '__main__':
        t = MyThread()
        t.start()
        print('主线程')
    

    3.线程与进程之间的对比

    1. 速度的对比

      from threading import Thread
      def task(name):
          print(f'{name} is running')
      if __name__ == '__main__':
          t = Thread(target=task,args=('mcsaoQ',))
          t.start()
          print('主线程')
      '''
      线程绝对要比进程要快:
          mcsaoQ is running
          主线程
      '''
      
    2. pid

      # pid 进程号
      from threading import Thread
      import os
      def task():
          print(f'子线程: {os.getpid()}')
      if __name__ == '__main__':
          t = Thread(target=task,)
          t.start()
          print(f'主线程: {os.getpid()}')
      
    3. 线程之间共享资源

      from threading import Thread
      import time
      x = 1000
      def task():
           time.sleep(3)
           print('子线程....')
      def main():
           print('111')
           print('222')
           print('333')
      if __name__ == '__main__':
           t = Thread(target=task)
           t.start()
           # t.join()
           main()
      

    4.线程的其他方法

    from threading import Thread
    import threading
    import time
    def task(name):
         time.sleep(1)
         print(f'{name} is running')
         print(threading.current_thread().name)
    if __name__ == '__main__':
         for i in range(5):
             t = Thread(target=task,args=('mcsaoQ',))
             t.start()
         # 线程对象的方法:
         # time.sleep(1)
         # print(t.is_alive())  # 判断子线程是否存活  ***
         # print(t.getName())  # 获取线程名
         # t.setName('线程111')
         # print(t.getName())  # 获取线程名
         # threading模块的方法:
         # print(threading.current_thread().name)  # MainThread
         # print(threading.enumerate())  # 返回一个列表 放置的是所有的线程对象
         print(threading.active_count())  # 获取活跃的线程的数量(包括主线程)
         print('主线程')
    

    5.守护线程

    守护: 子守护主, 只要主结束,子马上结束.
    主线程什么时候结束???
    多线程是同一个空间,同一个进程,进程代表 空间,资源. 静态的.主线程是进程空间存活在内存中的必要条件.
    主线程: 必须要等待所有的子线程全部结束之后,你在执行完毕,进程在消失.
    守护线程必须等待主线程结束才结束, 主线程必须等待所有的非守护线程结束才能结束.
    守护线程: 必须等待所有的非守护线程以及主线程结束之后才能够结束.

    from threading import Thread
    import time
    def foo():
        print(123)
        time.sleep(3)
        print("end123")
    def bar():
        print(456)
        time.sleep(1)
        print("end456")
    if __name__ == '__main__':
        t1=Thread(target=foo)
        t2=Thread(target=bar)
        t1.daemon = True
        t1.start()
        t2.start()
        print("main-------")
    

    6.互斥锁(锁)

    互斥锁,锁,同步锁都是一把锁.

    互斥锁与join区别?

    互斥锁 随机抢锁,公平. join 提前排好顺序,不公平.但是都是串行.

    1563953747387

    7.死锁现象,递归锁

    递归锁: 递归锁是一把锁,锁上有记录,只要acquire一次,锁上就计数1次, acquire2次,锁上就计数2次,release1次,减一, 只要递归锁计数不为0,其他线程不能抢.

    from threading import Thread
    from threading import Lock
    from threading import RLock
    import time
    # lock_A = RLock()
    # lock_B = RLock()
    lock_A = lock_B = RLock()
    class MyThread(Thread):
        def run(self):
            # lock_A.acquire()
            # lock_B.acquire()
            # print(111)
            # lock_A.release()
            # lock_B.release()
            self.f1()
            self.f2()
        def f1(self):
            lock_A.acquire()
            print(f'{self.name}拿到 A锁')
            lock_B.acquire()  # 第二个线程抢B锁
            print(f'{self.name}拿到 B锁')
            lock_B.release()
            lock_A.release()
        def f2(self):
            lock_B.acquire()
            print(f'{self.name}拿到 B锁')
            time.sleep(1)  # 第一个线程 睡1秒
            lock_A.acquire()  # 第一个线程抢A锁
            print(f'{self.name}拿到 A锁')
            lock_A.release()
            lock_B.release()
    if __name__ == '__main__':
        # for i in range(3):
        #     t = MyThread()
        #     t.start()
        t1 = MyThread()
        t1.start()
        t2 = MyThread()
        t2.start()
        t3 = MyThread()
        t3.start()
        print('主线程')
    

    8.信号量

    之前讲的锁都是只允许一个线程或者进程进入.信号量允许多个线程或者进程同时进入

    from threading import Thread
    from threading import current_thread
    from threading import Semaphore
    import time
    import random
    sm = Semaphore(4)
    # lock= Lock()
    def go_public_wc():
        sm.acquire()
        print(f'{current_thread().name}正在厕所')
        time.sleep(random.randint(1, 3))
        sm.release()
    if __name__ == '__main__':
        for i in range(20):
            t = Thread(target=go_public_wc)
            t.start()
        # print('主')
    
  • 相关阅读:
    数据库练习
    数据库的设计范式知识
    asserts文件存到外部SD卡里
    用户的注册信息存储到文件里,登录成功后读出并显示出来
    java快速排序引起的StackOverflowError异常
    并发入库面临重复数据的问题
    《旅行青蛙》安卓版本修改钱和奖券
    ddmlib问题总结——同步获取设备信息
    Java ArrayList中对象的排序 (Comparable VS Comparator)
    Authentication(Spring Security 认证笔记)
  • 原文地址:https://www.cnblogs.com/hql1117/p/11239545.html
Copyright © 2011-2022 走看看