线程初识

  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}')
原文地址:https://www.cnblogs.com/-777/p/11396476.html