如何提交单个cpu上的利用率?---------------------------------------异步IO
异步IO主要应用在网站应用上,比如一个网站有1万个连接,但其实真正干事的不多,
如果采用被动的轮询模式浪费太大,
所以要用到主动的异步IO,即不需要轮询(我不需要知道你的状态,你干完活给我说一声行了),
然后你交出空闲cpu的模式,这样虽然一万个连接但系统资源的占用就很低
但只适合网站中大并发即有很多时间就是在等的情况,并不适合计算密集型的并发,密集计算型的主要看CPU的多少
可以大大提高单线程的效率
其实就是把一个任务交给一个人,你不用一直询问工作进度,你只需要等待他干完活后给你说一声
而异步IO就可以提供实现说一声的机制
减少无效的cpu占用时间,在单个cpu上发挥出最大的效率(不用再一直看子进程的工作状态了)
这样cpu就没有闲置的不干活的状态(不干活相当于骗到时间后在等子进程的时间,只是时间占用不占用CPU)
相似的功能在windows用的是IOCompletionPort
在Linux中用的是epoll,(一般是高性能服务器)
异步编程模块asyncio:
asyncio为什么叫异步IO,其实是和cpu计算密集型的对比的结果并不是只是IO,也可以搞其他的东西
发送网络请求并获取网站头信息:
#yield from在改程序中的作用都是交出cpu使用权
import asyncio
#这个装饰器告诉这个函数它是一个支持异步IO的协程
@asyncio.coroutine
def wget(host):
#连对方的80端口(建立异步连接),当然这需要耗费时间
connect = asyncio.open_connection(host, 80)
#连接成功后返回reader,writer即在等的时候就yield出去了,剩下的cpu资源你们随便拿
#即连接的过程中有一段时间是不需要cpu的
reader, writer = yield from connect
header = 'GET / HTTP/1.0\r\nHost: %s\r\n\r\n' % host
print(header)
#在发指令的过程中有一段时间是不需要cpu的,他占用的是网络带宽,在这段时间里把cpu贡献出来
writer.write(header.encode('utf-8'))
yield from writer.drain()
while True:
#看对方返回来的信息(返回的是字节码不是字符串:b'\r\n')
line = yield from reader.readline()
if line == b'\r\n':
break
print('%s header > %s' % (host, line.decode('utf-8').rstrip()))
writer.close()
'''
for循环的单线程与asyncio循环的单线程效率比较
'''
loop = asyncio.get_event_loop()
tasks = [wget(host) for host in ['www.sina.com', 'www.sohu.com', 'www.163.com']]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
异步编程框架:
python有异步编程框架Twisted: Reactor模式:消息等待处理循环
该框架可以大大简化异步编程代码实现(既要能实现还要有高性能)