博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python中的协程:greenlet和gevent
阅读量:4567 次
发布时间:2019-06-08

本文共 2125 字,大约阅读时间需要 7 分钟。

python中的协程:greenlet和gevent

  • 协程是一中多任务实现方式,它不需要多个进程或线程就可以实现多任务。

1.通过yield实现协程:

代码:

import timedef A():    while 1:        print('------A-----')        time.sleep(0.1)        yield()def B():    while 1:        print('-------B-----')        time.sleep(0.1)        next(a)a = A()B()

执行结果:

-------B-----------A------------B-----------A------------B-----------A------------B-----------A------------B-----------A-----···

2.greenlet:

  • yield能实现协程,不过实现过程不易于理解,greenlet是在这方面做了改进。

上代码:

from greenlet import greenletimport timedef A():    while 1:        print('-------A-------')        time.sleep(0.5)        g2.switch()def B():    while 1:        print('-------B-------')        time.sleep(0.5)        g1.switch()g1 = greenlet(A)  #创建协程g1g2 = greenlet(B)g1.switch()  #跳转至协程g1

执行结果:

-------A--------------B--------------A--------------B--------------A-------···

3.gevent:

  • greenlet可以实现协程,不过每一次都要人为的去指向下一个该执行的协程,显得太过麻烦。python还有一个比greenlet更强大的并且能够自动切换任务的模块gevent
  • gevent每次遇到io操作,需要耗时等待时,会自动跳到下一个协程继续执行。

上代码:

import geventdef A():    while 1:        print('-------A-------')        gevent.sleep(1) #用来模拟一个耗时操作,注意不是time模块中的sleepdef B():    while 1:        print('-------B-------')        gevent.sleep(0.5)  #每当碰到耗时操作,会自动跳转至其他协程g1 = gevent.spawn(A) # 创建一个协程g2 = gevent.spawn(B)g1.join()  #等待协程执行结束g2.join()

执行结果:

-------A--------------B--------------B--------------A--------------B--------------B--------------A--------------B--------------B-------···

4.协程gevent完成回显服务器:

import geventfrom gevent import monkey,socketmonkey.patch_all()   #有IO才做时需要这一句s = socket.socket(2,1)  #用的都是gevent模块中的socket,但用法一样s.setsockopt(1,2,1)s.bind(('',8080))s.listen(1024)def func_accept():    while 1:        cs,userinfo = s.accept()        print('来了一个客户'+str(userinfo))        g = gevent.spawn(func_recv,cs)  #每当有用户连接,增加一条协程def func_recv(cs):    while 1:        recv_data = cs.recv(1024)        print(recv_data)  #程谁堵塞了,便会跳转至其他协程        if len(recv_data) > 0:            cs.send(recv_data)        else:            cs.close()            breakg1 = gevent.spawn(func_accept)g1.join()
  • gevent的代码风格和线程非常相似,运行出来后的效果也非常相似。

转载于:https://www.cnblogs.com/PrettyTom/p/6628569.html

你可能感兴趣的文章
【转】HDU 6194 string string string (2017沈阳网赛-后缀数组)
查看>>
前后端分离
查看>>
存储过程
查看>>
生成器
查看>>
将一个数的每一位都取出来的方法!
查看>>
2) 十分钟学会android--建立第一个APP,执行Android程序
查看>>
面试题8:二叉树下的一个节点
查看>>
hash冲突的解决方法
查看>>
Asp.Net webconfig中使用configSections的用法
查看>>
mysql 二进制日志
查看>>
阻止putty变成inactive
查看>>
TP框架代码学习 学习记录 3.2.3
查看>>
doc文档生成带目录的pdf文件方法
查看>>
js数组,在遍历中删除元素(用 for (var i in arr)是无效的 )
查看>>
通过前端上传图片等文件的方法
查看>>
在 OC 中调用 Swift 代码
查看>>
Android仿腾讯应用宝 应用市场,下载界面, 有了进展button
查看>>
安卓|五大逆向软件下载
查看>>
5 OK6410裸机调试(不用Jlink)
查看>>
“模板”学习笔记(5)-----编译器在处理函数模板的时候都干了啥
查看>>