gpt4 book ai didi

python - 如何像在 C# 中一样同步运行 Python 协程,直到第一次等待?

转载 作者:行者123 更新时间:2023-12-05 04:39:27 25 4
gpt4 key购买 nike

我正在处理一些 asyncio Python 代码,我遇到了协程排序问题。我有一些使用 C# 的经验,所以我将使用它作为示例。

在 C# 中我可以写:

using System;
using System.Threading.Tasks;

public class Program
{
async static Task<int> foo(int n, int delay)
{
Console.WriteLine("Foo start {0}",n);
await Task.Delay(delay);
Console.WriteLine("Foo end {0}",n);
return 0;
}

public static void Main()
{
Task<int> t1 = foo(1,300);
Task<int> t2 = foo(2,200);

Task.WaitAll(new []{t2,t1});// Reverse on purpose
}
}

结果如下,注意协程的开始与调用顺序相匹配,不是等待顺序。由于协程函数如何划分到生成器中,因此可以保证这一点。 IE。它们总是同步运行,直到第一个 await

Foo start 1
Foo start 2
Foo end 2
Foo end 1

但是当我在 Python 中做同样的事情时,我得到不同的顺序。

import asyncio
async def foo(n,delay):
print(f"Foo start {n}")
await asyncio.sleep(delay/1000)
print(f"Foo end {n}")
return 0


async def main():
t1 = foo(1,300)
t2 = foo(2,200)

await asyncio.gather(t2,t1) # Reverse on purpose

asyncio.run(main())
Foo start 2
Foo start 1
Foo end 2
Foo end 1

我也知道这是为什么 - 因为 foo(1,300) 返回一个生成器,该生成器在等待/安排协程之前不会启动。

我的问题是如何在 Python 中实现类似 C# 的行为,这意味着协程会在调用时不间断地启动,直到第一次await

我试过了

t1 = asyncio.create_task(foo(1,300))
t2 = asyncio.create_task(foo(2,200))

哪个解决了这个问题,但调度顺序真的有保证吗?

最佳答案

asyncio.create_task(),顾名思义,创建一个task.Task实例。任务在 task.Task 的构造函数中安排

self._loop.call_soon(self.__step, context=self._context)

来自 BaseEventLoop.call_soon 的文档字符串:

Arrange for a callback to be called as soon as possible.This operates as a FIFO queue: callbacks are called in theorder in which they are registered. Each callback will becalled exactly once.

因此,只要您使用的事件循环不会覆盖此行为,我会说您可以按照您想要的方式使用 create_task。据我所知,asyncio 中的事件循环都没有。

关于python - 如何像在 C# 中一样同步运行 Python 协程,直到第一次等待?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70448827/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com