python并发编程(二):协程

‘‘‘协程:      1. 协程的定义:        1) 是一种用户态的轻量级线程, 即协程是由用户程序自己控制调度的        2) 是一种协作而非抢占式的处理并发方式, A --> B ---> A --> C        3) 协程的切换属于程序级别的, 操作系统不需要切换     

     2. 协程的特点:         1) 协程本身是一个线程, 是用户态的切换         2) 相比线程优点:                       1> 切换没有消耗                        2> 修改共享程序不需要加锁         3) 相比线程缺点:            一旦引入协程,就需要检测单线程下所有的IO行为, 实现遇到IO就切换,少一个都不行,因为一旦一个任务阻塞了,整个线程就阻塞了

     3. 并发要求:         1) 要控制多个任务之间的切换          2) 切换之前要把当前任务状态保存下来        (yield, greenlet无法检测IO)         3) 可以自动检测IO操作, 在IO阻塞下发生切换   (geven可以检测IO)    ‘‘‘ # 协程

‘‘‘协程实现:     1. 生成器: yield, next(g), g.send(value)       用法:            yield                      # 可以保存状态            g = generator()            # 创建生成器            next(g)                    # 检测到最近yield位置, 执行yield之前的代码            g.send(value)              # 检测当前yield的位置,把值通过该yield传入,执行下一个yield到该yield之间的代码, 然后返回

    2. greenlet: 使任意函数变为生成器       用法:           g = greenlet.greenlet(fun)    # 将函数包装为生成器           g.switch(*args,**kwargs)      # 在一个函数中切换到fun  

    3. gevent: 可自动完成IO阻塞切换       用法:           1) g = gevent.spawn(func,*args,**kwargs)  # 相当于创建了一个虚拟线程对象, 可自动识别IO阻塞                                                     # 协程创建时就已经运行了

           2) 若要gevent识别其他类型阻塞, 必须在导入该模块前打补丁              from gevent import monkey;monkey.patch_all()

           3) g.join()                               # 协程加入主线程(真实线程)              gevent.joinall([])                     # 线程可能出现协程还没执行完, 线程就结束了, 所有协程必须join到主线程

           4) g.value                                # 获取协程返回值

       gevent实现单线程socket并发: Gevent_Server.py    ‘‘‘ # 协程实现

原文地址:https://www.cnblogs.com/lancelotxly/p/10843611.html

时间: 2024-11-05 21:52:11

python并发编程(二):协程的相关文章

python并发编程之协程

阅读目录 一 引子 二 协程介绍 三 Greenlet 四 Gevent介绍 五 Gevent之同步与异步 六 Gevent之应用举例一 七 Gevent之应用举例二 一 引子 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制),一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长 ps:在介绍进程理论时,提

python并发编程之---协程

1.什么是协程 协程:是单线程下的并发,又称微线程,纤程. 协程是一种用户态的轻量级线程,协程是由用户程序自己控制调度的. 2.需要注意的点: 需要强调的是: #1. python的线程属于内核级别的,即由操作系统控制调度(如单线程遇到io或执行时间过长就会被迫交出cpu执行权限,切换其他线程运行) #2. 单线程内开启协程,一旦遇到io,就会从应用程序级别(而非操作系统)控制切换,以此来提升效率(!!!非io操作的切换与效率无关) 对比操作系统控制线程的切换,用户在单线程内控制协程的切换 优点

Python并发编程:协程介绍

一 引子 基于单线程来实现并发,即只用一个主线程(很明显可利用的CPU只有一个)情况下实现并发,先回顾一下并发的本质:切换+保存状态 CPU正在运行一个任务,会在两种情况下切走去执行其它的任务(切换由操作系统强制控制),一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长或有一个优先级更高的程序替代了它 ps:在介绍进程理论时,提及进程的三种执行状态,而线程才是执行单位,所以也可以将上图理解为线程的三种状态 一:其中第二种情况并不能提升效率,只是让CPU能够雨露均沾,实现看起来所有任务

Python学习:python并发编程之协程

本节内容: 1.协程介绍. 2.回顾yield 3.Greenlet 4.Gevent介绍 5.Gevent之同步与异步 6.Gevent之应用举例一 7.Gevent应用举例二 一.引子 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制),一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长 ps:在介绍进

Python 之并发编程之协程

一.协程 ''' def gen(): for i in range(10): yield i # 初始化生成七函数 返回生成器对象,简称生成器 mygen = gen() for i in mygen: print(i) ''' # (1) 用协程改写成生产者消费者 ''' def producer(): for i in range(100): yield i def consumer(): g = producer() for i in g: print(i) ''' # (2) 协程的具

python 高性能编程之协程

用 greenlet 协程处理异步事件 自从 PyCon 2011 协程成为热点话题以来,我一直对此有着浓厚的兴趣.为了异步,我们曾使用多线程编程.然而线程在有着 GIL 的 Python 中带来的性能瓶颈和多线程编程的高出错风险,"协程 + 多进程"的组合渐渐被认为是未来发展的方向.技术容易更新,思维转变却需要一个过渡.我之前在异步事件处理方面已经习惯了回调 + 多线程的思维方式,转换到协程还非常的不适应.这几天我非常艰难地查阅了一些资料并思考,得出了一个可能并不可靠的总结.尽管这个

并发编程之协程

对于单线程下,我们不可避免程序中出现io操作,但如果我们能在自己的程序中(即用户程序级别,而非操作系统级别)控制单线程下的多个任务能在一个任务遇到io阻塞时就切换到另外一个任务去计算,这样就保证了该线程能够最大限度地处于就绪态,即随时都可以被cpu执行的状态,相当于我们在用户程序级别将自己的io操作最大限度地隐藏起来,从而可以迷惑操作系统,让其看到:该线程好像是一直在计算,io比较少,从而更多的将cpu的执行权限分配给我们的线程. 协程的本质就是在单线程下,由用户自己控制一个任务遇到io阻塞了就

Python并发实践_02_协程

python中实现并发的方式有很多种,通过多进程并发可以真正利用多核资源,而多线程并发则实现了进程内资源的共享,然而Python中由于GIL的存在,多线程是没有办法真正实现多核资源的. 对于计算密集型程序,应该使用多进程并发充分利用多核资源,而在IO密集型程序中,多核优势并不明显,甚至由于大多数时间都是在IO堵塞状态,多进程的切换消耗反而让程序效率更加低下. 而当需要并发处理IO密集型任务时,就需要用到协程(Coroutine).协程并没有系统级的调度,而是用户级的调度方式,避免了系统调用的开销

网络编程进阶:并发编程之协程、IO模型

协程: 基于单线程实现并发,即只用一个主线程(此时可利用的CPU只有一个)情况下实现并发: 并发的本质:切换+保存状态 CPU正在运行一个任务,会在两种情况下切走去执行其他任务(切换有操作系统强制控制),一种情况是该任务发生了阻塞,另一种是该任务计算的时间过长或有一个优先级更高的程序替代了它 在介绍进程理论时,提及进程的三种执行状态,而线程才是执行单位,所以也可以将上图理解为线程的三种状态 如果多个任务都是纯计算的,上图的情况2并不能提升效率,因为只是让CPU来回切,这样看起来所有任务都被"同时