day10---异步I/O,gevent协程

时间:2022-09-12 22:48:47

协程

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

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

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

协程的好处:

  • 无需线程上下文切换的开销
  • 无需原子操作锁定及同步的开销
  • 方便切换控制流,简化编程模型
  • 高并发+高扩展性+低成本:一个CPU支持上万的协程都不是问题。所以很适合用于高并发处理。

缺点:

  • 无法利用多核资源:协程的本质是个单线程,它不能同时将 单个CPU 的多个核用上,协程需要和进程配合才能运行在多CPU上.当然我们日常所编写的绝大部分应用都没有这个必要,除非是cpu密集型应用。
  • 进行阻塞(Blocking)操作(如IO时)会阻塞掉整个程序

使用yield实现协程操作例子    

import time
import queue
def consumer(name):
print("--->starting eating baozi...")
while True:
new_baozi = yield
print("[%s] is eating baozi %s" % (name,new_baozi))
#time.sleep(1) def producer(): r = con.__next__()
r = con2.__next__()
n = 0
while n < 5:
n +=1
con.send(n)
con2.send(n)
print("\033[32;1m[producer]\033[0m is making baozi %s" %n ) if __name__ == '__main__':
con = consumer("c1")
con2 = consumer("c2")
p = producer()
#!/usr/bin/env python
#-*- coding:utf-8 -*-
# Author:DCC
from greenlet import greenlet
import gevent
'''
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()
'''
def foo():
print("Running in foo")
gevent.sleep(4)
print("switch to foo")
def bar():
print("Running in bar")
gevent.sleep(1)
print("已经调到bar")
def func3():
print("Running in func3")
gevent.sleep(2)
print("func3 again") gevent.joinall([
gevent.spawn(foo),
gevent.spawn(bar),
gevent.spawn(func3),
])

遇到IO阻塞时会自动切换任务

爬虫

#!/usr/bin/env python
#-*- coding:utf-8 -*-
# Author:DCC
from urllib import request
import gevent,time
from gevent import monkey
monkey.patch_all()#把当前程序的所有的IO操作单独做上标记
#之前 gevent是不是捕获 urllib的IO操作的,所有,无法进行切换
def f(url):
print("GET: %s" % url)
resp = request.urlopen(url)
data = resp.read()
print("%d bytes received from %s." % (len(data),url)) urls = [
"https://www.python.org/",
"https://www.yahoo.com/",
"https://github.com/"
]
start_time = time.time()
for url in urls:
f(url)
print("同步cost",time.time()-start_time)
async_start_time = time.time()
gevent.joinall([
gevent.spawn(f,"https://www.python.org/"),
gevent.spawn(f,"https://www.yahoo.com/"),
gevent.spawn(f,"https://github.com/"),
])
print("异步cost",time.time()-async_start_time)

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

server side

import sys
import socket
import time
import gevent from gevent import socket,monkey
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(8001)

client side 

import socket

HOST = 'localhost'    # The remote host
PORT = 8001 # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
while True:
msg = bytes(input(">>:"),encoding="utf8")
s.sendall(msg)
data = s.recv(1024)
#print(data) print('Received', repr(data))
s.close()

day10---异步I/O,gevent协程的更多相关文章

  1. Python之路-python&lpar;Queue队列、进程、Gevent协程、Select&bsol;Poll&bsol;Epoll异步IO与事件驱动&rpar;

    一.进程: 1.语法 2.进程间通讯 3.进程池 二.Gevent协程 三.Select\Poll\Epoll异步IO与事件驱动 一.进程: 1.语法 简单的启动线程语法 def run(name): ...

  2. Python进阶----异步同步&comma;阻塞非阻塞&comma;线程池&lpar;进程池&rpar;的异步&plus;回调机制实行并发&comma; 线程队列&lpar;Queue&comma; LifoQueue&comma;PriorityQueue&rpar;&comma; 事件Event&comma;线程的三个状态&lpar;就绪&comma;挂起&comma;运行&rpar; &comma;&ast;&ast;&ast;协程概念&comma;yield模拟并发&lpar;有缺陷&rpar;&comma;Greenlet模块&lpar;手动切换&rpar;&comma;Gevent&lpar;协程并发&rpar;

    Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就 ...

  3. python2&period;0&lowbar;s12&lowbar;day9&lowbar;协程&amp&semi;Gevent协程

    Python之路,Day9 - 异步IO\数据库\队列\缓存 本节内容 Gevent协程 Select\Poll\Epoll异步IO与事件驱动 Python连接Mysql数据库操作 协程 1.协程,又 ...

  4. gevent协程、select IO多路复用、socketserver模块 改造多用户FTP程序例子

    原多线程版FTP程序:http://www.cnblogs.com/linzetong/p/8290378.html 只需要在原来的代码基础上稍作修改: 一.gevent协程版本 1. 导入geven ...

  5. python并发编程之gevent协程&lpar;四&rpar;

    协程的含义就不再提,在py2和py3的早期版本中,python协程的主流实现方法是使用gevent模块.由于协程对于操作系统是无感知的,所以其切换需要程序员自己去完成. 系列文章 python并发编程 ...

  6. 什么是协程?与线程和进程对比优劣在哪?gevent协程示例代码

      协程 协程,又称微线程,纤程.英文名Coroutine..一句话说明什么是线程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在 ...

  7. PHP下的异步尝试三:协程的PHP版thunkify自动执行器

    PHP下的异步尝试系列 如果你还不太了解PHP下的生成器和协程,你可以根据下面目录翻阅 PHP下的异步尝试一:初识生成器 PHP下的异步尝试二:初识协程 PHP下的异步尝试三:协程的PHP版thunk ...

  8. Python Gevent协程自动切换IO

    Gevent Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程. Gr ...

  9. python gevent 协程

    简介 没有切换开销.因为子程序切换不是线程切换,而是由程序自身控制,没有线程切换的开销,因此执行效率高, 不需要锁机制.因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断 ...

随机推荐

  1. Python之Web框架

    Python之Web框架: 一.  Web框架的本质: 对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. #!/usr/bin/env pyth ...

  2. Node&period;js的学习路线

    http://www.admin10000.com/document/4624.html 顺便关注一下博客:http://blog.fens.me/series-nodejs/ php socket框 ...

  3. js call apply

    参考文章:https://www.zhihu.com/question/20289071 引用:call 和 apply 都是为了改变某个函数运行时的 context 即上下文而存在的,换句话说,就是 ...

  4. SQL笔记----在一个关系表中操作列

    使用alter关键字,可以为一个表添加新的列. 比如: 给Persons的表中添加一列,名字为Birthday,类型是date. ALTER TABLE Persons ADD Birthday da ...

  5. Servlet路径跳转1---使用相对路径和绝对路径&comma;在页面上调用servlet的路径写法(超链接的方式和表单的方式)

    课程1-13   http://www.imooc.com/video/5554 Servlet路径跳转: 绝对路径:放在任何地方都对的路径 相对路径:相对于当前资源的路径 index文件 加上/,表 ...

  6. C&num; WCF学习笔记(二)终结点地址与WCF寻址&lpar;Endpoint Address and WCF Addressing&rpar; WCF中的传输协议

    URI的全称是 Uniform Rosource Identifire(统一资源标识),它唯一标识一个确定的网绐资源,同时也表示资源所处的位置及访问的方式(资源访问所用的网络协议). 对于Endpoi ...

  7. Python 内置函数汇总

    循环设计与循环对象 range() enumerate() zip() iter() 函数对象 map() filter() reduce() 序列操作 all([True, 1, "hel ...

  8. maven依赖jar包更新,业务jar需同步更新(业务jar依赖API)

    背景: 环境出现问题,定位为依赖jar缺失,修改工程pom文件补充依赖jar. 更新要点说明: 依赖jar,更新提交 业务jar,也需更新提交:maven构建会把依赖jar引用进去,更新环境如果单独更 ...

  9. 一个python小爬虫

    自定义获取豆瓣网电影TOP250里的排名数量 主要思路:先由requests库获取html基本信息,然后用BeautifulSoup来进行html.parser格式解析,逐个获取Tag属性,并且对内容 ...

  10. CodeForces512C-Pluses everywhere-模拟&sol;数学&sol;排列组合模板

    经过研究可以发现,每一位的贡献是C(n-2,k-1)+C(n-3,k-1)...C(k-1,k-1) 同时还要注意加号全部在左边的情况. 这里还用了O(n)预处理O(1)组合数的模板.//妙啊..妙. ...