首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python 学习手册
Python Cookbook
Python 基础教程
Python Sites
PyPI - Python Package Index
http://www.simple-is-better.com/
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
Coding
V2EX  ›  Python

Python 中怎么使用 async 写一个协程函数

  •  
  •   aoscici2000 · 249 天前 · 1371 次点击
    这是一个创建于 249 天前的主题,其中的信息可能已经有所发展或是发生改变。

    网上列举了不少例子, 基本都是使用 asyncio.sleep()来模拟, 但基本没说这个是如何实现非阻塞的, 也有说普通函数加个 async 就是协程函数了, 然后试了一下使用普通函数加个 async 关键字替代 asyncio.sleep, 行不通, 并不是同时执行的. 能简单给个例子不用官方的 sleep 是怎么实现这个协程的吗?

    
    from datetime import datetime
    import asyncio
    
    async def add(n):
        print(datetime.now().strftime('%H:%M:%S.%f'))
        count = 0
        for i in range(n):
            count += i
        print(datetime.now().strftime('%H:%M:%S.%f'))
        return count
    
    async def fun(n):
        res = await add(n)
        print(f'res = {res}')
    
    loop = asyncio.get_event_loop()
    tasks = [fun(20000000), fun(30000000)]
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()
    
    
    10 回复  |  直到 2019-04-10 09:41:42 +08:00
        1
    silkriver   249 天前
    asyncio 是指异步 IO,对 IO 密集型操作有效,你这又不是 IO 操作能有什么用
        2
    keepeye   249 天前
    asyncio.sleep() 可以用来模拟异步 io 但你的 add 方法里面没有异步操作啊。另外同时执行是伪命题,单线程,不可能同时执行的
        3
    aoscici2000   249 天前 via iPhone
    @keepeye 最大疑问就是这个了,如果我需要 add 方法变成异步操作,那是不是也得单独开一个线程执行?如果是那感觉写起来也繁琐阿,为什么都说 async 这个关键字大大简化了异步操作了呢。
        4
    Leigg   249 天前 via iPhone
    因为多数人自己都没明白,都是在模仿
        5
    keepeye   249 天前
    @aoscici2000 如果你是为了防止耗时计算阻塞主线程,可以使用 loop.run_in_executor,通过别的线程处理完了再回调
        6
    rexyan   249 天前
    可以看下 aiomysql 的 demo
        7
    exiledkingcc   248 天前   ♥ 2
    你没搞清楚异步是什么。
    比如一个函数 f 需要执行 a,b,c 三个步骤操作,耗时比如是 1ms,100ms,1ms。其中 b 是 io 操作,比如网络请求,需要等待结果返回。而需要执行多个 f()。同步的情况就是:
    a();b();c();a();b();c();一共需要 204ms。
    异步的情况就是:
    a();b(),然后 b()中阻塞了,直接返回,开始执行第二个任务的 a(),b(),第二个 b()也阻塞了,然后就等待 io 完成,再然后执行后面的。一共需要 105ms。
    异步不是“同时执行”,而是原来同步需要等待 io,异步下可以去执行其它的 cpu 任务,这样就节约了原来浪费掉的 cpu 时间。看上去像是“同时执行”,实际上是“同时等待”,cpu 执行时间没法减少。
    asyncio.sleep 实际上就是让出 cpu 去执行别的任务,某个时间后再唤醒。
        8
    Wicked   248 天前 via iPhone
    感觉楼主需要的是并行,python 没法多线程并行
        9
    wwqgtxx   248 天前
    asyncio 的主要用途在于等待 IO 操作,你这程序从头到尾都不涉及到 IO 操作( python 不目前支持异步 stdout ),当然没有任何作用,建议你对比一下 requests 和 aiohttp 并发请求网络资源的代码就知道区别了
        10
    lucahhai   248 天前
    简化异步操作仅仅是指 async/await 代替了 @asyncio.coroutine/yield from 而已吧
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2410 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 24ms · UTC 05:50 · PVG 13:50 · LAX 21:50 · JFK 00:50
    ♥ Do have faith in what you're doing.