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

2019-04-09 10:44:41 +08:00
 aoscici2000

网上列举了不少例子, 基本都是使用 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()

2693 次点击
所在节点    Python
10 条回复
silkriver
2019-04-09 10:49:18 +08:00
asyncio 是指异步 IO,对 IO 密集型操作有效,你这又不是 IO 操作能有什么用
keepeye
2019-04-09 11:13:45 +08:00
asyncio.sleep() 可以用来模拟异步 io 但你的 add 方法里面没有异步操作啊。另外同时执行是伪命题,单线程,不可能同时执行的
aoscici2000
2019-04-09 11:47:45 +08:00
@keepeye 最大疑问就是这个了,如果我需要 add 方法变成异步操作,那是不是也得单独开一个线程执行?如果是那感觉写起来也繁琐阿,为什么都说 async 这个关键字大大简化了异步操作了呢。
Leigg
2019-04-09 12:06:48 +08:00
因为多数人自己都没明白,都是在模仿
keepeye
2019-04-09 12:11:27 +08:00
@aoscici2000 如果你是为了防止耗时计算阻塞主线程,可以使用 loop.run_in_executor,通过别的线程处理完了再回调
rexyan
2019-04-09 12:14:46 +08:00
可以看下 aiomysql 的 demo
exiledkingcc
2019-04-09 16:40:03 +08:00
你没搞清楚异步是什么。
比如一个函数 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 去执行别的任务,某个时间后再唤醒。
Wicked
2019-04-09 18:25:28 +08:00
感觉楼主需要的是并行,python 没法多线程并行
wwqgtxx
2019-04-09 18:57:05 +08:00
asyncio 的主要用途在于等待 IO 操作,你这程序从头到尾都不涉及到 IO 操作( python 不目前支持异步 stdout ),当然没有任何作用,建议你对比一下 requests 和 aiohttp 并发请求网络资源的代码就知道区别了
lucays
2019-04-10 09:41:42 +08:00
简化异步操作仅仅是指 async/await 代替了 @asyncio.coroutine/yield from 而已吧

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/553254

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX