zoukankan      html  css  js  c++  java
  • 线程初识

    1. 进程: 生产者消费者模型

      1. 编程思想,模型,设计模式,理论等等,都是交给你一种编程的方法,以后你遇到类似的情况套用即可

      2. 生产者消费者三要素:生产者:产生数据的

        ​ 消费者:接收数据做进一步处理的

        ​ 容器:盆(队列)

        队列容器作用:缓冲的作用,平衡生产力与消费力,解耦

      from multiprocessing import Process
      from multiprocessing import Queue
      import time
      import random
      
      def producer(q,name):
          for i in range(1,6):
              time.sleep(random.randint(1,2))
              res = f'{i}号包子'
              q.put(res)
              print(f'生产者{name}生产了{res}')
      def consumer(q,name):
          while 1:
              try:
                  food = q.get(timeout=3)
                  time.sleep(random.randint(1,3))
                  print(f'消费者{name}吃了{food}')
              except Exception:
                  return
      if __name__ == '__main__':
          q = Queue()
          p1 = Process(target=producer,args=(q,'上约'))
          p2 = Process(target=consumer,args=(q,'海购'))
          p1.start()
          p2.start()
      
    2. 线程的理论知识

      1. 什么是线程(一条流水线的工作流程)
        1. 开启一个进程:在内存中开启一个进程空间,然后将主进程的所有的资源数据复制一份,然后调用线程去执行代码
        2. 进程是资源单位,线程是执行单位
      2. 线程vs进程
        1. 开启进程的开销非常大,比开启线程的开销大很多.
        2. 开启线程的速度非常快.要快几十倍到上百倍.
        3. 线程线程之间可以共享数据,进程与进程之间需借助队列等方法实现通信.
      3. 线程的应用
        1. 并发: 一个cpu 看起来像是同时执行多个任务.
        2. 单个进程开启三个线程.并发的执行任务.
        3. 开启三个进程并发的执行任务.
        4. 开启多线程就非常好了:数据共享, 开销小,速度快.
    3. 开启线程的两种方式

      第一种:函数的方式
      
      # from threading import Thread
      # import time
      # def task(name):
      #     print(f'{name} is running')
      #     time.sleep(1)
      #     print(f'{name} is gone')
      #
      # if __name__ == '__main__':
      #     t1 = Thread(target=task,args=('长兴',))
      #     t1.start()
      #     print('==主线程')
      
      第二种:类的方式
      from threading import Thread
      import time
      class MyThread(Thread):
          def __init__(self,name):
              super().__init__()
              self.name = name
          def run(self):
              print(f'{self.name} is running')
              time.sleep(1)
              print(f'{self.name} is gone')
      if __name__ == '__main__':
          t1 = MyThread('长兴')
          t1.start()
          print('===主线程')
      
    4. 线程vs进程的代码对比

      1. 开启速度对比
      # 多进程
      # from threading import Thread
      # from multiprocessing import Process
      # import os
      # def work():
      #     print('hello')
      # if __name__ == '__main__':
      #     t = Process(target=work)
      #     t.start()
      #     print('主线程/主进程')
      永远先执行主进程代码
      
      
      # 多线程
      from threading import Thread
      import time
      def task(name):
          print(f'{name} is running')
          time.sleep(1)
          print(f'{name} is gone')
      if __name__ == '__main__':
          t1 = Thread(target=task,args=('海购',))
          t1.start()
          print('===主线程')
      
      1. 对比pid
      # from multiprocessing import Process
      # import time
      # import os
      # def task(name):
      #     print(f'子进程:{os.getpid()}')
      #     print(f'主进程:{os.getppid()}')
      # if __name__ == '__main__':
      #     p=Process(target=task,args=('长兴',))
      #     p2=Process(target=task,args=('长兴2',))
      #     p.start()
      #     p2.start()
      #     print(f'主进程{os.getpid()}')
      
      
      # 线程
      from threading import Thread
      import os
      def task():
          print(os.getpid())
      if __name__ == '__main__':
          t1 = Thread(target=task)
          t2 = Thread(target=task)
          t1.start()
          t2.start()
          print(f'===主线程{os.getpid()}')
      线程没有pid进程号,所求是该线程依赖的进程的pid号
      
      1. 同一个进程内线程共享内部数据
      from threading import Thread
      import os
      x = 3
      def task():
          global x
          x = 100
      if __name__ == '__main__':
          t = Thread(target=task)
          t.start()
          t.join()
          print(f'==主线程{x}')
      同一进程内的资源数据对于这个进程的多个线程来说是共享的
      
    5. 线程的相关其他方法

      Thread实例对象的方法
        # isAlive(): 返回线程是否活动的。
        # getName(): 返回线程名。
        # setName(): 设置线程名。
      
      threading模块提供的一些方法:
        # threading.currentThread(): 返回当前的线程变量。
        子线程:<Thread(线程1, started 11252)>
        主线程:<_MainThread(MainThread, started 5256)>
        
        # threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
        [<_MainThread(MainThread, started 5256)>]      一个列表
        
        # threading.activeCount(): 返回正在运行的线程数量,len(threading.enumerate())有相同的结果。
      
      from threading import Thread
      from threading import currentThread
      from threading import enumerate
      from threading import activeCount
      import os
      import time
      x = 3
      def task():
          print(currentThread())
          time.sleep(1)
          print('666')
      print(123)
      if __name__ == '__main__':
          t1 = Thread(target=task,name='线程1')
          t2 = Thread(target=task,name='线程2')
          t1.start()
          t2.start()
          time.sleep(2)
          print(t1.isAlive())
          print(t1.getName())
          t1.setName('子线程-1')
          print(t1.name)
          print(currentThread())
          print(enumerate())
          print(activeCount())
          print(f'===主线程{os.getpid()}')
      
    6. 守护线程

      # join:阻塞,告知主进程要等待我子进程结束之后,再执行主进程
      from threading import Thread
      import time
      def task(name):
          print(f'{name} is running')
          time.sleep(1)
          print(f'{name} is gone')
      if __name__ == '__main__':
          start_time = time.time()
          t1 = Thread(target=task,args=('海购',))
          t2 = Thread(target=task,args=('海购1',))
          t3 = Thread(target=task,args=('海购2',))
          t1.start()
          t1.join()
          t2.start()
          t2.join()
          t3.start()
          t3.join()
          print(f'===主线程{time.time()-start_time}')
          
          ===主线程3.0048482418060303
          
      # 守护进程
      from multiprocessing import Process
      import time
      def foo():
          print(123)
          time.sleep(1)
          print('end123')
      def bar():
          print(456)
          time.sleep(2)
          print('end456')
      if __name__ == '__main__':
          p1 = Process(target=foo,)
          p2 = Process(target=bar,)
          p1.daemon = True
          p1.start()
          p2.start()
          print('==主')
          
          ==主
          456
          end456
          
      # 守护线程
      from threading import Thread
      import time
      def sayhi(name):
          print('你滚!')
          time.sleep(2)
          print(f'{name} say hello')
      if __name__ == '__main__':
          t = Thread(target=sayhi,args=('长兴',))
          t.daemon = True/t.setdaemon(True)
          t.start()#线程的开启速度要比进程快很多
          print('主线程')
          
          你滚!
          主线程 
      -------------------------------------***------------------------------------
      from threading import Thread
      import time
      def foo():
          print(123)
          time.sleep(1)
          print('end123')
      
      def bar():
          print(456)
          time.sleep(3)
          print('end456')
      t1 = Thread(target=foo)
      t2 = Thread(target=bar)
      t1.daemon = True
      t1.start()
      t2.start()
      print('main------')
      
      123
      456
      main------
      end123
      end456
      主线程什么时候结束?
      守护线程	等待	非	守护	子线程以及	主线程结束	之后,结束
      
      from threading import Thread
      import time
      def foo():
          print(123)
          time.sleep(3)
          print('end123')
      
      def bar():
          print(456)
          time.sleep(1)
          print('end456')
      t1 = Thread(target=foo)
      t2 = Thread(target=bar)
      t1.daemon = True
      t1.start()
      t2.start()
      print('main------')
      
      
          123
          456
          main------
          end456
      
    7. 互斥锁

      # from threading import Thread
      # import time
      # import random
      # x = 100
      #
      # def task():
      #     time.sleep(random.randint(1,2))
      #     global x
      #     temp = x
      #     time.sleep(random.randint(1, 3))
      #     temp = temp - 1
      #     x = temp
      #
      #
      # if __name__ == '__main__':
      #     l1 = []
      #     for i in range(100):
      #         t = Thread(target=task)
      #         l1.append(t)
      #         t.start()
      #
      #     for i in l1:
      #         i.join()
      #     print(f'主线程{x}')
      
      # 多个任务公抢一个数据,保证数据的安全的目的,要让其串行
      
      
      from threading import Thread
      from threading import Lock
      import time
      import random
      x = 100
      
      def task(lock):
      
          lock.acquire()
          # time.sleep(random.randint(1,2))
          global x
          temp = x
          time.sleep(0.01)
          temp = temp - 1
          x = temp
          lock.release()
      
      
      if __name__ == '__main__':
          mutex = Lock()
          for i in range(100):
              t = Thread(target=task,args=(mutex,))
              t.start()
      
          time.sleep(3)
         print(f'主线程{x}')
  • 相关阅读:
    洛谷P3292 [SCOI2016]幸运数字 线性基+倍增
    2019牛客暑期多校第五场题解ABGH
    暑假集训-8.1总结
    主席树
    2019HDU多校第四场题解
    洛谷P4570 [BJWC2011]元素 线性基
    暑假集训-7.31总结
    线性基总结
    Proj. THUIoTFuzz Paper Reading: One Engine to Fuzz 'em All: Generic Language Processor Testing with Semantic Validation
    UVALive5876-Writings on the Wall-KMP
  • 原文地址:https://www.cnblogs.com/-777/p/11396476.html
Copyright © 2011-2022 走看看