python爬虫(二十一)-------------------异步IO

如何提交单个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模式:消息等待处理循环

该框架可以大大简化异步编程代码实现(既要能实现还要有高性能)

猜你喜欢

转载自blog.csdn.net/qq_41228218/article/details/89008211