Python基础-协程(20)

协程

概念:

  • 比线程更小的执行单元
  • 某个函数,可以在任何地方保存当前函数的一些临时变量信息,然后切换到另一个函数去执行
  • 进程和线程是系统切换,协程自己主动让出CPU
  • 协程的切换只是单纯的操作CPU的上下文,比线程的切换更快速
  • 1:N模式,就是让一个线程作为容器,里面放置多个协程
  • IO密集型程序适用于协程,CPU密集型程序不适用于协程

协程编程-greenlet

  • py中greenlet模块对协程进行了封装
  • 安装模块:sudo pip install greenlet
from greenlet import greenlet
import time
def fun1():
    while True:
        print("---A---")
        #切换协程
        g2.switch()
        time.sleep(1)
def fun2():
    while True:
        print("--B--")
        g1.switch()
        time.sleep(1)
g1=greenlet(fun1)
g2=greenlet(fun2)
#切换到g1执行
g1.switch()

协程编程-gevent

  • pip install gevent
    py中还有一个比greenle更强大的可以自动切换任务的模块gevent。
    当一个greenlet遇见IO时(网络,文件操作等),比如访问网络,就自动切换到其它greenlet,等到IO操作完成,在在适合的时候切换回来。
模拟自动切换协程编程
import gevent
def fun(n):
    for i in range(n):
        #打印协程信息
        print('%s%s'%(gevent.getcurrent,i))
        #模拟耗时操作,实现协程自动切换
        gevent.sleep(1)
#创建协程
g1=gevent.spawn(fun,4)
g2=gevent.spawn(fun,4)
g3=gevent.spawn(fun,4)
g1.join()
g2.join()
g3.join()


协程编写TCP服务器
from gevent import socket,monkey,spawn
#打补丁,作用就是将标准库中对应的socket和thread替换掉
monkey.patch_all()
#客户端处理
def handlerequest(con):
    while True:
        data=con.recv(1024)
        if not data:
            con.close()
            break
        else:
            print(data)
#创建服务器
def server(port):
    s=socket.socket()
    s.bind(('127.0.0.1',port))
    s.listen(5)
    while True:
        cli,addr=s.accept()
        spawn(handlerequest,cli)
if __name__=="__main__":
    server(55555)

你可能感兴趣的:(Python基础)