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、多线程、多进程

最新文章

  1. 用sublime写出的第一个网页
  2. CentOS6.4 配置HAProxy+Keepalived
  3. TCL语言笔记:TCL中的列表操作
  4. 1189: [HNOI2007]紧急疏散evacuate - BZOJ
  5. rhel_6.x 安装mysql
  6. AJAX背景技术介绍
  7. Mockito使用注意事项
  8. C#设计模式之七适配器模式(Adapter)【结构型】
  9. Django-rest-framework源码分析----权限
  10. Saltstack基础
  11. eclipse开发安卓时logcat的绿色加号不见了
  12. C# 利用Unity 实现IOC+AOP
  13. python 3.7 方向键乱码
  14. gulp 编译es6 react 教程 案例 配置
  15. OCP考试062题库出现大量新题-18
  16. 【bzoj2844】 albus就是要第一个出场
  17. 26-三个水杯(bfs)
  18. WPF的DatePicker--日期选择器
  19. 北京Uber优步司机奖励政策(1月5日)
  20. 软件工程项目组Z.XML会议记录 2013/09/18

热门文章

  1. 移动端rem单位适配使用
  2. Python3学习笔记19-继承和多态
  3. 转载:abstract的方法是否可同时是static,是否可同时是native,是否可同时是synchronized?
  4. linux 后台运行nohup & ctrl+z
  5. 测试开发之前端——No6.HTML5中的键盘事件
  6. tsconfig.json配置
  7. Deep Learning系统实训之二:梯度下降原理
  8. 目标检测-ssd
  9. HRBUST - 1818 石子合并 区间dp入门
  10. python 全栈开发,Day18(对象之间的交互,类命名空间与对象,实例的命名空间,类的组合用法)