异步Python:循环阻塞/非阻滞

发布于 2025-01-25 08:02:03 字数 1162 浏览 2 评论 0原文

这是我遇到的有趣情况。我不久前写了一些代码,这些代码是同步的,但后来我切换到异步。以下代码类似于异步代码。

async def some_coroutine(args, obj): 
   genarg1, genarg2 = args
   for (param1, param2) in some_generator(genarg1, genarg2): 
     await asyncio.sleep(0) # do this to prevent blocking and give control to event loop
     # do work
     for i in enumerate(param2):
        await asyncio.sleep(0) # do this to prevent blocking and give control to event loop 
        obj.somefunc(i, param1)
     pass

我想重构上述内容,以便可以使其与某些非ASYNC代码兼容。我曾经拥有它,可以在自己的功能中调用for循环,但这会阻止Eventloop。我不希望他们不时地控制事件循环而接管事件循环。我想对这样的事情进行重构,但无法弄清楚如何避免它的阻塞方面:

async def some_coroutine(args, obj):
   genarg1, genarg2 = args
   somefunc(genarg1, genarg2, obj)

def somefunc(genarg1, genarg2, obj):
   for (param1, param2) in some_generator(genarg1, genarg2): 
     # do work
     for i in enumerate(param2):
        obj.somefunc(i, param1)
     pass

显然,第一个代码块,协议试图不阻止事件循环,因为代码是一个例程,并且等待Asyncio.sleep(0)。但是现在,重组的代码将for循环分开,并且正在阻止,我无法将等待asyncio.sleep(0)放在某个func中。我想以这种方式对代码进行重新处理,以便我可以从其他不使用Eventloop的功能(例如,测试用例)中调用它。

这是可能的还是我只是在考虑错误(即,对代码的重构不同)?

This is an interesting situation I have come across. I wrote some code a while back that was synchronous but then I switched to async. The following code resembles the async code.

async def some_coroutine(args, obj): 
   genarg1, genarg2 = args
   for (param1, param2) in some_generator(genarg1, genarg2): 
     await asyncio.sleep(0) # do this to prevent blocking and give control to event loop
     # do work
     for i in enumerate(param2):
        await asyncio.sleep(0) # do this to prevent blocking and give control to event loop 
        obj.somefunc(i, param1)
     pass

I want to refactor the above such that I can make it compatible with some of the non-async code. I used to have it where the for loops can be called in their own functions except this would block the eventloop. I don't want them to take over the event loop without giving control back to the event loop from time to time. I'd like to refactor to something like this but can't figure out how to avoid the blocking aspect of it:

async def some_coroutine(args, obj):
   genarg1, genarg2 = args
   somefunc(genarg1, genarg2, obj)

def somefunc(genarg1, genarg2, obj):
   for (param1, param2) in some_generator(genarg1, genarg2): 
     # do work
     for i in enumerate(param2):
        obj.somefunc(i, param1)
     pass

Clearly, the first code block, the protocol attempted to not block the event loop because the code was in one routine and had await asyncio.sleep(0). But now the refactored code breaks apart the for loop and is blocking and I'm not able to place await asyncio.sleep(0) in somefunc. I'd like to refactor the code this way so I could call it from other functions that don't use eventloops (e.g., test cases) but when an eventloop is used, I'd prefer it to be versatile enough to not block it.

Is this possible or am I just thinking about it wrong (i.e., refactor the code differently)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文