python并发编程(二):协程

三世轮回 提交于 2020-01-04 05:08:58
'''协程:      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    ''' # 协程实现
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!