网上列举了不少例子, 基本都是使用 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()
1
silkriver 2019-04-09 10:49:18 +08:00
asyncio 是指异步 IO,对 IO 密集型操作有效,你这又不是 IO 操作能有什么用
|
2
keepeye 2019-04-09 11:13:45 +08:00
asyncio.sleep() 可以用来模拟异步 io 但你的 add 方法里面没有异步操作啊。另外同时执行是伪命题,单线程,不可能同时执行的
|
3
aoscici2000 OP @keepeye 最大疑问就是这个了,如果我需要 add 方法变成异步操作,那是不是也得单独开一个线程执行?如果是那感觉写起来也繁琐阿,为什么都说 async 这个关键字大大简化了异步操作了呢。
|
4
Leigg 2019-04-09 12:06:48 +08:00 via iPhone
因为多数人自己都没明白,都是在模仿
|
5
keepeye 2019-04-09 12:11:27 +08:00
@aoscici2000 如果你是为了防止耗时计算阻塞主线程,可以使用 loop.run_in_executor,通过别的线程处理完了再回调
|
6
rexyan 2019-04-09 12:14:46 +08:00
可以看下 aiomysql 的 demo
|
7
exiledkingcc 2019-04-09 16:40:03 +08:00 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 2019-04-09 18:25:28 +08:00 via iPhone
感觉楼主需要的是并行,python 没法多线程并行
|
9
wwqgtxx 2019-04-09 18:57:05 +08:00
asyncio 的主要用途在于等待 IO 操作,你这程序从头到尾都不涉及到 IO 操作( python 不目前支持异步 stdout ),当然没有任何作用,建议你对比一下 requests 和 aiohttp 并发请求网络资源的代码就知道区别了
|