42.线程概念及线程池

进程:是CPU分配资源的最小单位

  • CPU时间片:CPU处理的时间长度
  • 进程是CPU分配资源的最小单位
    • 光有进程没有办法高效里用CPU资源
    • 处理进程等待时,进程会做IO等待,从而浪费时间,无法高效利用cpu
  • 内存独立:
    • 进程切换了,彼此多个进程不会影响
    • A,B,C,3个进程相互独立,不管ABC怎么切换,数据不会乱
    • 一个进程挂掉,其他进程不会有事情

线程:CPU执行的最小单位

  • 轻量级的进程:线程是**内存共享**
    • CPU寄存器,计算器
    • 切换简单,CPU在切换执行任务的时候,损耗的时间少
    • 但是由于线程存在GIL锁(Golbal Lock),维持全局的线程同步执行,导致最大的缺点就是没有办法实现真正并发
    • 最大的优点是线程等待时IO可以切换,高效利用CPU资源
  • GIL锁的存在由此推论出Cpython中的多线程执行就是同步的:按照顺序,一个个来
  • 进程:PID Process
  • 线程也有:TID Thread
    • 只在当前的内存空间下有用
  • 线程如果父进程退出,那么全部子线程,都会退出
    • 主线程死亡,子线程死亡
    • 为了保持线程的稳定性,主线程一般不要做大事,不要业务处理,只做开启任务
    • 没有孤儿线程,僵尸线程会有但是无所谓不重要
  • 数据通信:
    • 本身内存共享,list,dict,str,int,这些数据都可以直接共享
  • GIL:
    • 大锁,全局锁,直接锁掉线程,维持全局的线程同步执行,影响并发,未来说不定这个东西就没有了
  • from threading import Thread
    • Process(target,args,)
    • t = Thread(target,args,name,kwargs)
      • t.start() 真正开启线程
      • t.join() 回收线程资源
  • #线程创建
    from threading import Thread
    import time
    def work_a(a):
        for var in range(100000):
            a[0] += 1
    def work_b(a):
        for var in range(100000):
            a[0] = a[0] * 3
    def work_c(a):
        for var in range(50000):
            a[0] = a[0] - 1
    def main():
        a = [1]
        start = time.time()
        t = Thread(target=work_a,args=(a,))
        t.start()
        t1 = Thread(target=work_b,args=(a,))
        t1.start()
        t2 = Thread(target=work_c,args=(a,))
        t2.start()
        for var in [t,t1,t2]:
            var.join()
        end = time.time()
        print('耗时:%.2f' % (end - start))
    if __name__ == "__main__":
        main()
    

    运行结果:

    耗时:0.49
    
  • #线程数据共享,数据都可以直接共享
    from threading import Thread
    def work_a(a):
        a[0] = 'a'
    def main():
        a = [1]
        t = Thread(target=work_a,args=(a,))
        t.start()
        t.join()
        print(a)
    if __name__ == "__main__":
        main()
    

    运行结果:

    ['a']
    
  • 列外:

    • 只有纯计算没有IO的时候,多线程等同于单进程
      • 甚至是多线程效率低于单进程
    • 多进程:多核心电脑
      • 计算密集的时候,多进程最快-->单进程-->多线程
    • 多线程:
      • IO密集
      • 比如:操作文件,QQ聊天的时候用多线程比较好

  

线程池:

  • from multiprocessing.pool import ThreadPool 
    • 引入线程池模块
  • thread_pool= ThreadPool(5)             
    • 创建5个线程池
  • p=thread_pool.apply_async(func,args,)   
    • 非阻塞行为,并发的,无序的 
  • #非阻塞的会返回一个抽象的数据,调用值得时候需要用get函数(p.get())
  • p.close(),p.join()    最后关闭跟回收线程

   

原文地址:https://www.cnblogs.com/zhangan/p/10294843.html