本文转自:http://blog.csdn.net/hairetz/article/details/16119911

  • 进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度。
  • 线程拥有自己独立的栈和共享的堆,共享堆,不共享栈,线程亦由操作系统调度(标准线程是的)。
  • 协程和线程一样共享堆,不共享栈,协程由程序员在协程的代码里显示调度。

进程和其他两个的区别还是很明显的。

打个比方吧,假设有一个操作系统,是单核的,系统上没有其他的程序需要运行,有两个线程 A 和 B ,A 和 B 在单独运行时都需要 10 秒来完成自己的任务,而且任务都是运算操作,A B 之间也没有竞争和共享数据的问题。现在 A B 两个线程并行,操作系统会不停的在 A B 两个线程之间切换,达到一种伪并行的效果,假设切换的频率是每秒一次,切换的成本是 0.1 秒(主要是栈切换),总共需要 20 + 19 * 0.1 = 21.9 秒。如果使用协程的方式,可以先运行协程 A ,A 结束的时候让位给协程 B ,只发生一次切换,总时间是 20 + 1 * 0.1 = 20.1 秒。如果系统是双核的,而且线程是标准线程,那么 A B 两个线程就可以真并行,总时间只需要 10 秒,而协程的方案仍然需要 20.1 秒。

    #!/usr/bin/python
# python thread.py
# python -m gevent.monkey thread.py import threading class Thread(threading.Thread): def __init__(self, name):
threading.Thread.__init__(self)
self.name = name def run(self):
for i in xrange(10):
print self.name threadA = Thread("A")
threadB = Thread("B") threadA.start()
threadB.start()

python thread.py

A B A B ...

那么总共发生了 20 次切换:主线程 -> A -> B -> A -> B …

 #!/usr/bin/python
# python gr.py import greenlet def run(name, nextGreenlets):
for i in xrange(10):
print name
if nextGreenlets:
nextGreenlets.pop(0).switch(chr(ord(name) + 1), nextGreenlets) greenletA = greenlet.greenlet(run)
greenletB = greenlet.greenlet(run) greenletA.switch('A', [greenletB])

greenlet 是 python 的协程实现。

python gr.py

此时发生了 2 次切换:主协程 -> A -> B

python -m gevent.monkey thread.py

gevent 是基于 greenlet 的一个 python 库,它可以把 python 的内置线程用 greenlet 包装,这样在我们使用线程的时候,实际上使用的是协程,在上一个协程的例子里,协程 A 结束时,由协程 A 让位给协程 B ,而在 gevent 里,所有需要让位的协程都让位给主协程,由主协程决定运行哪一个协程,gevent 也会包装一些可能需要阻塞的方法,比如 sleep ,比如读 socket ,比如等待锁,等等,在这些方法里会自动让位给主协程,而不是由程序员显示让位,这样程序员就可以按照线程的模式进行线性编程,不需要考虑切换的逻辑。

gevent 版的命令发生了 3 次切换:主协程 -> A -> 主协程 -> B

再来说说 python 的线程,python 的线程不是标准线程,在 python 中,一个进程内的多个线程只能使用一个 CPU 。

如果使用 gevent 包装后的线程,程序员就不必承担调度的责任,而 python 的线程本身就没有使用多 CPU 的能力,那么,用 gevent 包装后的线程,取代 python 的内置线程,不是只有避免无意义的调度,提高性能的好处,而没有什么坏处了吗?

答案是否定的。举一个例子,有一个 GUI 程序,上面有两个按钮,一个 运算 一个 取消 ,点击运算,会有一个运算线程启动,不停的运算,点击取消,会取消这个线程,如果使用 python 的内置线程或者标准线程,都是没有问题的,即便运算线程不停的运算,调度器仍然会给 GUI 线程分配时间片,用户可以点击取消,然而,如果使用 gevent 包装后的线程就完蛋了,一旦运算开始,GUI 就会失去相应,因为那个运算线程(协程)霸着 CPU 不让位。不单是 GUI ,所有和用户交互的程序都会有这个问题。

python基础===进程,线程,协程的区别(转)的更多相关文章

  1. python的进程/线程/协程

    1.python的多线程 多线程就是在同一时刻执行多个不同的程序,然而python中的多线程并不能真正的实现并行,这是由于cpython解释器中的GIL(全局解释器锁)捣的鬼,这把锁保证了同一时刻只有 ...

  2. python进阶——进程/线程/协程

    1 python线程 python中Threading模块用于提供线程相关的操作,线程是应用程序中执行的最小单元. #!/usr/bin/env python # -*- coding:utf-8 - ...

  3. Python中进程线程协程小结

    进程与线程的概念 进程 程序仅仅只是一堆代码而已,而进程指的是程序的运行过程.需要强调的是:同一个程序执行两次,那也是两个进程. 进程:资源管理单位(容器). 线程:最小执行单位,管理线程的是进程. ...

  4. Python并发编程系列之常用概念剖析:并行 串行 并发 同步 异步 阻塞 非阻塞 进程 线程 协程

    1 引言 并发.并行.串行.同步.异步.阻塞.非阻塞.进程.线程.协程是并发编程中的常见概念,相似却也有却不尽相同,令人头痛,这一篇博文中我们来区分一下这些概念. 2 并发与并行 在解释并发与并行之前 ...

  5. Python 进程线程协程 GIL 闭包 与高阶函数(五)

    Python 进程线程协程 GIL 闭包 与高阶函数(五) 1 GIL线程全局锁 ​ 线程全局锁(Global Interpreter Lock),即Python为了保证线程安全而采取的独立线程运行的 ...

  6. python自动化开发学习 进程, 线程, 协程

    python自动化开发学习 进程, 线程, 协程   前言 在过去单核CPU也可以执行多任务,操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换任务2,任务2执行0.01秒,在切换到任务3,这 ...

  7. 多道技术 进程 线程 协程 GIL锁 同步异步 高并发的解决方案 生产者消费者模型

    本文基本内容 多道技术 进程 线程 协程 并发 多线程 多进程 线程池 进程池 GIL锁 互斥锁 网络IO 同步 异步等 实现高并发的几种方式 协程:单线程实现并发 一 多道技术 产生背景 所有程序串 ...

  8. 进程&线程&协程

    进程  一.基本概念 进程是系统资源分配的最小单位, 程序隔离的边界系统由一个个进程(程序)组成.一般情况下,包括文本区域(text region).数据区域(data region)和堆栈(stac ...

  9. python进程/线程/协程

    一 背景知识 顾名思义,进程即正在执行的一个过程.进程是对正在运行程序的一个抽象. 进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一.操作系统的其他所 ...

  10. python-socket和进程线程协程(代码展示)

    socket # 一.socket # TCP服务端 import socket # 导入socket tcp_sk = socket.socket() # 实例化一个服务器对象 tcp_sk.bin ...

随机推荐

  1. 移除 ios 上 input 的默认样式

    input{ -webkit-appearance:none; }

  2. ::before和::after 常见的用法

      .lizi:after{ content: "I'M after"; /*插入字符串*/ content: "attr(id)"; /*插入当前元素属性*/ ...

  3. 按照list中实体类的某一属性排序

    传进一个装有实体类的list public void sort(List<MedicalPracticesDetail> mpdList){ Collections.sort(mpdLis ...

  4. 为windows phone listbox 添加触摸倾斜效果

    在开发windows phone程序时,经常会用到listbox或者是longlistselector等列表控件.当点击时没有触摸效果体验会稍差一些,像windows phone中的设置页面一样,点击 ...

  5. Codeforces Round #517 Div. 1翻车记

    A:真的懵逼了.冷静了半天之后决定二分一下答案,然后先a安排上尽量小的再贪心地一个个扩大.40min才过.这个做法非常怂的以代码复杂度和时间复杂度为代价换取了比较稳的正确性,事实上由于1~n可以组合出 ...

  6. NOIP2002 提高组

    [NOIP2002] 提高组 T1.均分纸牌 算法:贪心(模拟) [分析]: 1.简化 2.过滤 3.辩证法  详见课件的例7 还有一种类似的思路是:求出平均值后,i←1 to n-1扫描,若a[i] ...

  7. lalala

    <script type="text/javascript"> var a_idx = 0; var b_idx = 0; var a = new Array(&quo ...

  8. 【刷题】BZOJ 4827 [Hnoi2017]礼物

    Description 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手 环,一个留给自己,一个送给她.每个手环上各有 n 个装饰物,并且每个装饰物都有一定的亮度.但是在 ...

  9. [luoguT30208]太极剑

    题面在这里 description 在一个圆环上给出\(n\)条端点在圆环上的绳子, 每次在圆环上切割的轨迹是一条直线,可以将可以将所有与这条直线相交的绳子切断. 求切割次数的最小值. data ra ...

  10. P2075 [NOIP2012T5]借教室 区间更新+二分查找

    P2075 [NOIP2012T5]借教室 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 noip2012-tg 描述 在大学期间,经常需要租借教室.大到院 ...