Python学习笔记18(协程)

协程,又称微线程,纤程。英文名Coroutine。一句话说明什么是线程:协程是一种用户态的轻量级线程。

协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。因此:

协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置。

那么,什么才能算是协程呢?

  1. 必须在只有一个单线程里实现并发
  2. 修改共享数据不需加锁
  3. 用户程序里自己保存多个控制流的上下文栈
  4. 一个协程遇到IO操作自动切换到其它协程

一、Greenlet

from greenlet import greenlet
 
 
def test1():
    print(12)
    gr2.switch()
    print(34)
    gr2.switch()
 
 
def test2():
    print(56)
    gr1.switch()
    print(78)
 
 
gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()

greenlet是一个用C实现的协程模块,可以使得你在任意函数之间随意切换。但是,这还不能算做是协程,毕竟切换还是我们自己手动切换的,没有遇到I/O自动切换。

二、Gevent

import gevent

def foo():
    print("Running in foo,foo开始>>>1")
    gevent.sleep(2)
    print('Explicit context switch to foo again  foo完成>>>6')

def bar():
    print('Explicit精确的 context 内容 to bar   bar开始>>>2')
    gevent.sleep(1)
    print("Imlicit context sitch back to bar  bar结束>>>5")

def func3():
    print('running func3  func3开始>>>3')
    gevent.sleep(0)
    print('running func3 again  func3结束>>>4')

gevent.joinall([
    gevent.spawn(foo),
    gevent.spawn(bar),
    gevent.spawn(func3),
])

Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程。 Greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。

通过Gevent实现单线程下的多socket并发

import sys
import socket
import time
import gevent

from gevent import socket, monkey #打补丁(把下面有可能有IO操作的单独做上标记)

monkey.patch_all()  #打补丁

def server(port):
    s = socket.socket()
    s.bind(('0.0.0.0', port))
    s.listen(500)
    while True:
        cli, addr = s.accept()
        gevent.spawn(handle_request, cli)


def handle_request(conn):
    try:
        while True:
            data = conn.recv(1024)
            print("recv:", data)
            conn.send(data)
            if not data:
                conn.shutdown(socket.SHUT_WR)

    except Exception as  ex:
        print(ex)
    finally:
        conn.close()


if __name__ == '__main__':
    server(9999)
协程之socket

 

posted @ 2017-08-29 15:11  爱锁屏  阅读(169)  评论(0编辑  收藏  举报