由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
Programming版 - python的async协程比go的麻烦多了啊
进入Programming版参与讨论
1 (共1页)
m*****n
发帖数: 3575
1
如果按照go,我可以在函数末尾写个重启的递归,
但是python的async就实现不了——
import asyncio
import time
loop = True
async def echo(n):
time.sleep(1)
print("echo:", n)
if loop:
asyncio.create_task(echo(n+1))
asyncio.run(echo(1))
time.sleep(5)
loop = False
time.sleep(1)
如果单看语义,你是不是觉得会输出5行?
实际只能输出2行:
echo: 1
echo: 2
m*****n
发帖数: 3575
2
asyncio.ensure_future也没用
Python关协程太勤快。
i*****9
发帖数: 3157
3
python啥时候有真线程了?

【在 m*****n 的大作中提到】
: asyncio.ensure_future也没用
: Python关协程太勤快。

n******t
发帖数: 4406
4
當你用了python你已經放棄性能了,還折騰幹啥?就一個腳本,能用就行了。

【在 m*****n 的大作中提到】
: 如果按照go,我可以在函数末尾写个重启的递归,
: 但是python的async就实现不了——
: import asyncio
: import time
: loop = True
: async def echo(n):
: time.sleep(1)
: print("echo:", n)
: if loop:
: asyncio.create_task(echo(n+1))

m*****n
发帖数: 3575
5
我放弃性能,但是没放弃功能啊!!!

【在 n******t 的大作中提到】
: 當你用了python你已經放棄性能了,還折騰幹啥?就一個腳本,能用就行了。
f*******t
发帖数: 7549
6
你自己代码不对,怪python干吗?python3 asyncio、Hack之类的coroutine什么都要
await,跟Java等传统语言的思路有点不同,多写几天习惯就好。Go的一个强大之处是
用sync的形式写async代码,所以大家喜欢。能输出正确结果(但非常ugly)的代码是:
import asyncio
loop = True
async def echo(n):
await asyncio.sleep(1)
print("echo:", n)
if loop:
await asyncio.create_task(echo(n+1))
async def stop_loop():
await asyncio.sleep(5)
global loop
loop = False
asyncio.run(asyncio.wait([
echo(1),
stop_loop(),
]))
m*****n
发帖数: 3575
7

await,跟Java等传统语言的思路有点不同,多写几天习惯就好。Go的一个强大之处是
用sync的形式写async代码,所以大家喜欢。能输出正确结果(但非常ugly)的代码是:
..............
async def stop_loop():
await asyncio.sleep(5)
global loop
loop = False
asyncio.run(asyncio.wait([
echo(1),
stop_loop(),
]))
谢谢你的提示。我有点懂了,asyncio.run本身是一个总的协程入口,里面必须要有一
个能等足够长时间的控制协程。换言之,如果是stop_loop自己刚开始开了echo(1),也
是可以的。

【在 f*******t 的大作中提到】
: 你自己代码不对,怪python干吗?python3 asyncio、Hack之类的coroutine什么都要
: await,跟Java等传统语言的思路有点不同,多写几天习惯就好。Go的一个强大之处是
: 用sync的形式写async代码,所以大家喜欢。能输出正确结果(但非常ugly)的代码是:
: import asyncio
: loop = True
: async def echo(n):
: await asyncio.sleep(1)
: print("echo:", n)
: if loop:
: await asyncio.create_task(echo(n+1))

f*******t
发帖数: 7549
8
主要问题是time.sleep把线程block了,coroutine不能正常运行

是:

【在 m*****n 的大作中提到】
:
: await,跟Java等传统语言的思路有点不同,多写几天习惯就好。Go的一个强大之处是
: 用sync的形式写async代码,所以大家喜欢。能输出正确结果(但非常ugly)的代码是:
: ..............
: async def stop_loop():
: await asyncio.sleep(5)
: global loop
: loop = False
: asyncio.run(asyncio.wait([
: echo(1),

y****w
发帖数: 3747
9
可能用python的swe们会钻的比较深吧,职业习惯。 我是把python当脚本用的,需要并
发就上Q。

是:

【在 f*******t 的大作中提到】
: 你自己代码不对,怪python干吗?python3 asyncio、Hack之类的coroutine什么都要
: await,跟Java等传统语言的思路有点不同,多写几天习惯就好。Go的一个强大之处是
: 用sync的形式写async代码,所以大家喜欢。能输出正确结果(但非常ugly)的代码是:
: import asyncio
: loop = True
: async def echo(n):
: await asyncio.sleep(1)
: print("echo:", n)
: if loop:
: await asyncio.create_task(echo(n+1))

f*******t
发帖数: 7549
10
“换言之,如果是stop_loop自己刚开始开了echo(1),也是可以的。”
不对,await不会跳过当前语句继续执行接下来的代码,只会把线程让给其它coroutine
。这两个函数必须并行invoke,不能在stop_loop里call echo。

是:

【在 m*****n 的大作中提到】
:
: await,跟Java等传统语言的思路有点不同,多写几天习惯就好。Go的一个强大之处是
: 用sync的形式写async代码,所以大家喜欢。能输出正确结果(但非常ugly)的代码是:
: ..............
: async def stop_loop():
: await asyncio.sleep(5)
: global loop
: loop = False
: asyncio.run(asyncio.wait([
: echo(1),

n******t
发帖数: 4406
11
用coroutine除了性能原因之外,有什麼意義嗎?
問題是這個python的coroutine,鬼知道下面是什麼實現的,可能還不如線程,搞來搞
去都是自己YY而已。

【在 m*****n 的大作中提到】
: 我放弃性能,但是没放弃功能啊!!!
m*****n
发帖数: 3575
12
年轻人想试验新玩意儿,给自己简历加分。
我接手后懒得大改了,就是这样。

【在 n******t 的大作中提到】
: 用coroutine除了性能原因之外,有什麼意義嗎?
: 問題是這個python的coroutine,鬼知道下面是什麼實現的,可能還不如線程,搞來搞
: 去都是自己YY而已。

d***a
发帖数: 13752
13
asyncio.run是用来运行协程主函数的。主函数退出了,asyncio.run就运行结束了,这
是为什么你的程序只打出两个echo。如果你把主函数的运行时间加长,可以打出更多的
echo。下面修改的程序可以打出5个echo。
import asyncio
import time
loop = True
async def echo(n):
await asyncio.sleep(1)
print("echo:", n)
if loop:
asyncio.create_task(echo(n+1))
await asyncio.sleep(5)
asyncio.run(echo(1))
time.sleep(5)
loop = False
time.sleep(1)
不过,从规范编程的角度来说,最好把异步主函数和其它异步函数分开,比如说定义一
个echo_main函数和一个echo函数。
另外,你的代码后面从time.sleep(5)开始,其实是无效的,不影响运行输出结果。

谢谢你的提示。我有点懂了,asyncio.run本身是一个总的协程入口,里面必须要有一
个能等足够长时间的控制协程。换言之,如果是stop_loop自己刚开始开了echo(1),也
是可以的。

【在 m*****n 的大作中提到】
: 年轻人想试验新玩意儿,给自己简历加分。
: 我接手后懒得大改了,就是这样。

m*****n
发帖数: 3575
14

的echo。
理解深刻!

【在 d***a 的大作中提到】
: asyncio.run是用来运行协程主函数的。主函数退出了,asyncio.run就运行结束了,这
: 是为什么你的程序只打出两个echo。如果你把主函数的运行时间加长,可以打出更多的
: echo。下面修改的程序可以打出5个echo。
: import asyncio
: import time
: loop = True
: async def echo(n):
: await asyncio.sleep(1)
: print("echo:", n)
: if loop:

1 (共1页)
进入Programming版参与讨论