GIL  Global  Interpreter  Lock
1 GIL:全局解释器锁
    GIL本质就是一把互斥锁,是夹在解释器身上的,
    同一个进程内的所有线程都需要先抢到GIL锁,才能执行解释器代码

为什么要GIL
    python 中内存管理依赖于 GC(一段用于回收内存的代码) 也需要一个线程
    除了你自己开的线程 系统还有一些内置线程   就算你的代码不会去竞争解释器  内置线程也可能会竞争
    所以必须加上锁

    当一个线程遇到了IO 同时解释器也会自动解锁  去执行其他线程  CPU会切换到其他程序

2、GIL的优缺点:
    优点:
        保证Cpython解释器内存管理的线程安全

    缺点:
        同一进程内所有的线程同一时刻只能有一个执行,
        也就说Cpython解释器的多线程无法实现并行


    在IO密集的程序中 CPU性能无法直接决定程序的执行速度    python就应该干这种活儿
    在计算密集的程序中  CPU性能可以直接决定程序的执行速度




GIL 和 自定义互斥锁的区别
  全局锁不能保证自己开启的线程安全  但是保证解释器中的数据的安全的
  GIL 在线程调用解释器时 自动加锁  在IO阻塞时或线程代码执行完毕时 自动解锁


#进程池vs线程池

#为什么要用“池”:
# 池子使用来限制并发的任务数目,限制我们的计算机在一个自己可承受的范围内去并发地执行任务

进程池
        就是一个装进程的容器
    为什么出现
        当进程很多的时候方便管理进程
    什么时候用?
        当并发量特别大的时候  (例如 双十一)
        很多时候进程是空闲的 就让他进入进程池  让有任务处理时才从进程池取出来使用
    进程池使用
        ProcessPoolExecutor类
        创建时指定最大进程数 自动创建进程
        调用submt函数将任务提交到进程池中
        创建进程是在调用submit后发生的

    总结一下:
        进程池可以自动创建进程
        进程限制最大进程数
        自动选择一个空闲的进程帮你处理任务

    进程什么时候算是空闲?
        代码执行完算是空闲

    进程池,并发的任务属于计算密集型
    线程池,并发的任务属于IO密集型