zoukankan      html  css  js  c++  java
  • Python 线程和进程和协程总结

    Python 线程和进程和协程总结

    线程和进程和协程

    进程

    • 进程是程序执行时的一个实例,是担当分配系统资源(CPU时间、内存等)的基本单位;

    • 进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响;

    • 进程间可以通过信号、信号量、共享内存、管道、队列等来进行通信;

    • 进程创建、销毁、上下文切换带来的开销成本都很大;

    线程

    • 线程是进程的一个实体,作为独立运行和独立调度的基本单位。

    • 线程可与同属一个进程的其他的线程共享进程所拥有的全部资源。

    • 线程只是一个进程中的不同执行路径,没有单独的地址空间,一个线程死掉就会导致整个进程死掉。

    • 线程创建、销毁、上下文切换带来的开销要比进程小得多;

    协程

    • 协程的控制有应用程序控制,非抢占式的;

    • 切换快,开销相较线程更小,所以可以开更多的协程;

    具体使用参考Python 协程总结

    多线程和多进程

    多线程

    优点

    1. 它是一种非常"节俭"的多任务操作方式。我们知道,在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种"昂贵"的多任务工作方式。而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且,线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。

    2. 线程间方便的通信机制,对不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用。

    3. 提高应用程序响应。这对图形界面的程序尤其有意义,当一个操作耗时很长时,整个系统都会等待这个操作,此时程序不会响应键盘、鼠标、菜单的操作,而使用多线程技术,将耗时长的操作(time consuming)置于一个新的线程,可以避免这种尴尬的情况。

    4. 使多CPU系统更加有效。操作系统会保证当前线程数不大于CPU数目时,不同的线程运行于不同的CPU上。

    GIL

    全局解释器锁是在实现Python解析器(CPython)时所引入的一个概念。每个线程在执行的过程都需要先获取GIL,保证同一时刻只有一个线程可以执行代码。

    Q&A: 为什么说GIL对于CPU密集型任务不友好,而对于IO密集型任务比较友好呢?

    这是因为GIL的释放逻辑是当前线程遇见IO操作或者ticks计数达到100(ticks可以看作是python自身的一个计数器,专门做用于GIL,每次释放后归零,这个计数可以通过 sys.setcheckinterval 来调整),进行释放。而每次释放GIL锁,线程进行锁竞争、切换线程,会消耗资源。

    那CPU密集型任务(各种循环处理、计数等等),在这种情况下,ticks计数很快就会达到阈值,然后触发GIL的释放与再竞争(多个线程来回切换当然是需要消耗资源的),但是对于IO密集型任务,多线程能够有效提升效率(单线程下有IO操作会进行IO等待,造成不必要的时间浪费,而开启多线程能在线程A等待时,自动切换到线程B,可以不浪费CPU的资源,从而能提升程序执行效率)。因此说GIL对于CPU密集型任务不友好,而对于IO密集型任务比较友好。

    解决方案

    multiprocessing库的出现很大程度上是为了弥补thread库因为GIL而低效的缺陷,它完整的复制了一套thread所提供的接口方便迁移。唯一的不同就是它使用了多进程而不是多线程。每个进程有自己的独立的GIL,因此也不会出现进程之间的GIL争抢。当然multiprocessing也不是万能良药。它的引入会增加程序实现时线程间数据通讯和同步的困难。Python的多线程在多核CPU上,只对于IO密集型计算产生正面效果;而当至少有一个CPU密集型线程存在时,那么多线程效率会由于GIL而大幅下降,这个时候就得使用多进程;

    多进程

    Python中的多线程因为GIL的关系并不算是真正的多线程,如果想要充分地使用多核CPU的资源,大部分情况需要使用多进程。multiprocessing支持子进程、通信和共享数据、执行不同形式的同步,提供了Process、Queue、Pipe、Lock等组件。

    谈谈python的GIL、多线程、多进程

  • 相关阅读:
    sqlserver sql优化案例及思路
    mysql执行计划常用说明
    MYSQL 的rownum
    innodb crash
    spring-mybatis源码追踪
    mylyn提交到JIRA的日期格式错误
    [google面试CTCI] 2-1.移除链表中重复元素
    [google面试CTCI] 2-0.链表的创建
    [google面试CTCI] 1-8.判断子字符串
    [google面试CTCI] 1-7.将矩阵中特定行、列置0
  • 原文地址:https://www.cnblogs.com/George1994/p/10615435.html
Copyright © 2011-2022 走看看