首页 > 解决方案 > 如何在 asyncio 中复制线程代码?

问题描述

我已经使用threading了多年,但它已经过时了,可能有很好的理由。因此,我试图了解这件事是如何运作的。

我的解决方案threading

考虑下面的threading代码:

import threading
import time

def say_wait_10():
    print("from say_wait_10 start")
    time.sleep(10)
    print("from say_wait_10 end")

def say():
    print("from say")

threading.Thread(target=say_wait_10).start()
threading.Thread(target=say).start()

这个想法是启动一个需要时间的任务say_wait_10()say()它们是独立的,一个不会阻塞另一个(这可能或多或少有效,具体取决于任务是 CPU 密集型还是 I/O 密集型)。

输出如预期的那样

from say_wait_10 start
from say
from say_wait_10 end

我试过的asyncio

我现在尝试asyncio按照文档将其转换为. 我想出了

import asyncio

async def say_wait_10():
    print("from say_wait_10 start")
    await asyncio.sleep(10)
    print("from say_wait_10 end")

async def say():
    print("from say")

async def main():
    await asyncio.create_task(say_wait_10())
    await asyncio.create_task(say())

asyncio.run(main())

我如何理解上面的代码是asyncio.create_task(say_wait_10())创建一个立即开始自行运行的任务。这await相当于threading.Thread.join()确保主代码等待协程(或上例中的任务)有时间​​完成。

输出是

from say_wait_10 start
from say_wait_10 end
from say

啊,所以任务中的代码是同步运行的,只有在完成之后才会say()被调用。这其中的异步部分在哪里?

然后我认为这await实际上可能意味着“等待”(让任务在继续之前完成)所以我删除了它,但这只是启动程序,运行主程序执行期间可运行的任何内容,然后结束了

from say_wait_10 start
from say

我的问题

如何复制我的threading代码 - 我非常感谢对代码中发生的事情的解释,以便我可以asyncio在继续之前掌握哲学。

或者,指向可以引导我的教程的指针threadingasyncio很棒。

笔记

如果这有帮助,我对 JS 中的 Promises 的想法没有任何问题,尽管对 JS 的理解非常肤浅(也就是说,比我在 Python 中的理解更肤浅——我只是一个业余开发人员)。在 JS 中,由于代码运行的位置,我没有问题可以想象“事情发生时会发生,然后它们会更新 DOM 的某些部分(这是我的典型用途))

标签: pythonpython-3.xpython-asynciopython-multithreading

解决方案


awaits是你的问题。await正在阻塞,因此您要say等到say_wait_10. 有几种方法可以实现您想要的。

第一个是一些变化

task = create_task(say_wait_10())
await say()
await task

如果您有两个以上的任务对它们花费的时间控制较少,这会变得有点混乱。另一种选择是

await gather(say_wait_10(), say())

推荐阅读