zoukankan      html  css  js  c++  java
  • day-37网路编程

    GIL锁:

      在 Cpython中,称为全局解释器锁 或者 称为GIL,是一个互斥锁.

      目的:是为了防止多个本地线程同一时间执行python字节码,

      这个锁是非常重要的,因为Cpython的内存管理是非线程安全的, ,然而这个GIL有存在的必要性, 因为有很多已经存在的代码,需要依赖这个锁

        非线程安全 即 多个线程访问同一个资源,会有有问题

        线程安全 即 多个线程访问同一个资源,不会有问题

      该锁只存在Cpython中,这并不是Python这们语言的 除了Cpython之外 Jpython, pypy,解释器

      之所以使用Cpython的原因??

        C编译过的结果可以计算机直接识别

        最主要的语言,C语言以后大量现成的,库(算法,通讯),Cpython可以无缝连接C语言的任何现成代码

      python 胶水 就是这也能干 那也能干

    内存管理

    垃圾回收机制

    python中不需要手动管理内存 ,C,OC

     

     

    引用计数

    a = 10 10地址次数计数为1

    b = a 计数2

    b = 1 计数1

    a = 0 计数0

    当垃圾回收启动后会将计数为0的数据清除掉,回收内存

     

     

    分代回收

     

     

    自动垃圾回收其实就是说,内部会有一个垃圾回收线程,会在某一时间运行起来,开始清理垃圾

    这是可能会产生问题,例如线程1申请了内存,但是还没有使用CPU切换到了GC,GC将数据当成垃圾清理掉了

    为了解决这个问题,Cpython就给解释器加上了互斥锁!

    为什么Cpython要这么设计???

    Cpython诞生于1991年 而多核处理器诞生2004年

    当时不需要考虑多核效率问题

    现在为什么不拿掉这个锁,因为这期间,很多已经完成的代码都依赖于这个锁,如果直接拿到,这些代码全得该,成本太大了

    GIL锁的加锁与解锁时机

    加锁: 只有有一个线程要使用解释器就立马枷锁

    释放:

      该线程任务结束

      该线程遇到IO

      该线程使用解释器过长 默认100纳秒

    GIL给我们造成的影响

    多线程不能并行

      案例:

      有一个下载任务 要从网络中下载一个文件 大小1G

      和转换 任务 使用input 转为大写输出

      上述任务并行执行,耗时也不会有太大的提升,反而开启多进程会浪费更多资源

      这种任务称之为IO密集型,大量的时间都花在IO等待

      这类问题使用多线程,

     

      计算密集型任务

      图像处理,语音处理,大数据分析,

    解决方案

    区分任务类型

      如果是IO密集使用多线程

      如果是计算密集使用多进程

    GIL锁与自定义锁的关系

    都是互斥锁

    为什么有了GIL还需要自己加锁

      GIL是加在解释器上的,只能锁住,解释器内部的资源,但是无法锁住我们自己开启资源

      例如: 我们自己开启了一个json文件,多个线程要同时访问, 如果第一个线程写入数据写到一半,执行超时了,另一个线程过来接着写,就会产生问题,

      自己开启共享资源还得自己所锁

      像是申请内存 保存数据等等就不需要我们程序员考虑了 GIL已经搞定了

    线程池与进程池

    线程池

    池就是容器,

    线程池就是装线程的容器

    好处:

      1.自动管理线程的开启和销毁

      2.自动分配任务给空闲的线程

      3.可以线程开启线程的数量 保证系统稳定

    信号量中是限制同时并发多少,但是线程已经全都建完了

    如何使用:

    1.创建池子

    2.submit 提交任务

    3.pool.shutdown() # 等待所有任务全部完毕 销毁所有线程 后关闭线程池

    关闭后就不能提交新任务了

    同步 异步

    在并发中 经常提及的几个概念:

     

    阻塞 - 非阻塞 程序的状态

      程序的运行状态 非阻塞 可能就绪 或者 运行

     

    并发 - 并行 多任务处理方式

     

      多个任务看起来像是同时运行 ,本质是切换+保存状态

      并行真正的同时进行中, 必须具备多核处理器

     

    同步 异步 任务提交(执行方式)方式

     

    同步               同步==阻塞 × 卡住 == 阻塞 ×

      指的是发起任务后,必须在原地等待,直到任务完成拿到结果 ,称之为同步

      默认情况就是同步的

    异步          异步 == 非阻塞 ×

      发起任务,不需要等待结果,可以继续执行其他代码,异步

      异步任务必须依赖,并发或并行, 在python中 通过多线程或多进程

      异步的效率明显高于同步

    异步回调

      异步指的是任务的提交方式是异步的

    异步任务的问题:

      如果这个任务执行完成后会产生返回值,任务发起方该何时去获取结果

    解决方案:

      异步回调

        异步回调指的就是一个函数,该函数会在任务后自动被调用,并且会传入Future对象 ,

        通过Future对象的result()获取执行结果 ,

        有了回调函数 就可以在任务完成时 及时处理它

     

     

    通常异步任务都会绑定一个回调函数,用来处理任务结果

     

     

    在进程池中回调函数是在父进程中执行,原因是 任务是由父进程发起的,所以结果也应该交给父进程

    在线程池中回调函数就在子线程中执行,原因是 线程之间数据本来是共享的

     

    如果你的任务结果需要交给父进程来处理,那建议回调函数,回调函数会自动将数据返回给父进程,不需要自己处理IPC

     

  • 相关阅读:
    #define IOFFSETOF(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
    互联网地址处理例程
    Android系统工程模式启动过程详解
    知识填充
    git 本地回退
    理解JS中的Promise对象
    MySQL server version for the right syntax to use near 'identified
    尾递归要注意的点
    事件捕获和事件冒泡的理解
    v 2ra-y_build_a_sever_in_vltru
  • 原文地址:https://www.cnblogs.com/klw1/p/10981861.html
Copyright © 2011-2022 走看看