美文网首页
Python协程(14)

Python协程(14)

作者: 纳米君 | 来源:发表于2018-07-29 17:44 被阅读26次

有了进程、线程,为什么还有个协程呢?
因为进程或线程的切换都是由操作系统决定的,存在切换开销问题,而协程的切换是由程序决定的,没有线程切换开销问题,执行性能更高些。当线程数量越多,协程优势更明显。
另外,协程是单线程的(也就无法利用多核CPU),操作共享变量不需要加锁,所以执行效率比多线程高。

Python的协程是通过生成器generator实现的,asyncio是Python 3.4版本引入的标准库,提供异步IO的支持。
以前的协程定义方式是在方法上加一个装饰器@asyncio.coroutine,新语法是在方法前加一个关键字async即可。相应的,方法里的yield from也要变成await

协程执行分以下4个步骤:

  1. 定义协程 async def get_test(url): pass
  2. 获取事件循环 loop = asyncio.get_event_loop()
  3. 获取tasks tasks = [get_test(url) for url in ['www.sina.com.cn', 'www.sohu.com', 'www.163.com']]
  4. 执行协程 协程并发时,loop.run_until_complete(asyncio.wait(tasks)),当只有一个协程时,loop.run_until_complete(get_test(url))

直接上代码:

  1. 装饰器方式:
import asyncio

@asyncio.coroutine
def get_test(url):
    conn = asyncio.open_connection(url, 80)
    reader, writer = yield from conn
    header = 'GET / HTTP/1.0\r\nHost: %s\r\n\r\n' % url
    writer.write(header.encode('utf-8'))
    yield from writer.drain()
    text = yield from reader.read()
    print('%s text > %s' % (url, text))
    writer.close()


loop = asyncio.get_event_loop()
tasks = [get_test(url) for url in ['www.sina.com.cn', 'www.sohu.com', 'www.163.com']]
# run_until_complete接受future,task是future的子类,接受coroutine时,会自动封装成task
loop.run_until_complete(asyncio.wait(tasks))
# 事件循环不再接受新的协程任务
loop.close()
  1. async方式:
import asyncio


async def get_test(url):
    conn = asyncio.open_connection(url, 80)
    reader, writer = await conn
    header = 'GET / HTTP/1.0\r\nHost: %s\r\n\r\n' % url
    writer.write(header.encode('utf-8'))
    await writer.drain()
    text = await reader.read()
    print('%s text > %s' % (url, text))
    writer.close()


loop = asyncio.get_event_loop()
tasks = [get_test(url) for url in ['www.sina.com.cn', 'www.sohu.com', 'www.163.com']]
# run_until_complete接受future,task是future的子类,接受coroutine时,会自动封装成task
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
  1. asyncio比较麻烦,需要自己定义报头,可以安装aiohttp库。aiohttp默认最大支持1024个协程同时进行,因此下面的代码加入了并发限制:
import asyncio

import aiohttp


async def get_test(url, semaphore):
    async with semaphore:
        async with aiohttp.ClientSession() as session:
            async with session.get(url) as res:
                print('%s text > %s' % (url, res.status))
                # 需要睡一会,才能体现并发限制效果,不能用time.sleep(2)
                await asyncio.sleep(2)
                return await res.read()


# aiohttp默认同时最大支持1024个协程的进行
semaphore = asyncio.Semaphore(2)
loop = asyncio.get_event_loop()
# 返回future对象
tasks = [asyncio.ensure_future(get_test(url, semaphore)) for url in
         ['https://www.sina.com.cn', 'https://www.sohu.com', 'https://www.163.com', 'https://www.sohu.com',
          'https://www.163.com', 'https://www.sohu.com', 'https://www.163.com']]
# run_until_complete接受future,task是future的子类,接受coroutine时,会自动封装成task
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
for v in tasks:
    print(v.result())

执行时,控制台每2s输出2个结果。

相关文章

  • python异步协程(aiohttp,asyncio)

    python异步协程 环境:python3.7.0 协程 协程,英文叫做 Coroutine,又称微线程,纤程,协...

  • Python协程(14)

    有了进程、线程,为什么还有个协程呢?因为进程或线程的切换都是由操作系统决定的,存在切换开销问题,而协程的切换是由程...

  • asyncio + asyncio 异步编程实例

    协程用法 接下来,我们来了解下协程的实现,从 Python 3.4 开始,Python 中加入了协程的概念,但这个...

  • Python 协程

    仅供学习,转载请注明出处 协程 协程,又称微线程,纤程。英文名Coroutine。 协程是啥 协程是python个...

  • 协程

    1.协程 协程,又称微线程,纤程。英文名Coroutine。 1.1 协程是什么 协程是python个中另外一种实...

  • Python并发编程——协程

    摘要:Python,协程,gevent 协程基本概念 协程,又称微线程,纤程。英文名Coroutine,是Pyth...

  • 协程介绍

    协程 协程,又称微线程,纤程。英文名Coroutine。 1.协程是什么? 协程是python个中另外一种实现多任...

  • 4-7

    协程 协程,又称微线程,纤程。英文名Coroutine。 协程是啥 协程是python个中另外一种实现多任务的方式...

  • 协程

    协程 协程,又称微线程,纤程。英文名Coroutine。 协程是啥 协程是python个中另外一种实现多任务的方式...

  • Python 协程 异步资料记录

    1. Python3.5协程原理 详细说明了Python协程产生的历史. 研究明白之后,写一篇文章,解释协程,并附...

网友评论

      本文标题:Python协程(14)

      本文链接:https://www.haomeiwen.com/subject/yeuzmftx.html