You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

关于Python中线程与异步结合场景下函数并行执行的疑问

关于Python中线程与异步结合场景下函数并行执行的疑问

先给你明确答案:你当前代码里的这两个函数并没有并行执行

为啥呢?你看main里的max(do_sync(1), await do_async(2))这行:

  • do_sync(1)是普通的同步函数,调用它的瞬间,主线程会直接卡在这里执行它的全部逻辑(加锁、计算、释放锁),等它完全跑完返回11之后,才会轮到await do_async(2)执行。相当于两个函数是按顺序排队跑的,根本没同时干活。

那怎么改成并行呢?其实咱们可以把同步函数放到单独的线程里跑,让它和异步任务同时执行,用asyncio的工具就能轻松实现,给你改个示例代码:

import asyncio
import threading

def do_sync(number: int) -> int:
    lock = threading.Lock()
    lock.acquire()
    result = number + 10
    lock.release()
    return result

async def do_async(number: int) -> int:
    result = number + 10
    return result

async def main():
    # 把同步函数丢到线程里执行,得到一个可等待的任务对象
    sync_task = asyncio.to_thread(do_sync, 1)
    # 直接创建异步任务
    async_task = do_async(2)
    
    # 同时等待两个任务完成,一次性拿到结果
    sync_result, async_result = await asyncio.gather(sync_task, async_task)
    
    # 最后取最大值
    result = max(sync_result, async_result)
    print(result)

if __name__ == "__main__":
    asyncio.run(main())

这里的关键是asyncio.to_thread,它会把同步函数do_sync放到一个单独的线程中执行,这样主线程的事件循环就可以同时处理do_async这个异步任务,两个任务就真正并行起来了。

另外提一句:你do_sync里的锁,在当前单个调用的场景下其实没啥用,只有当多个线程同时调用这个函数、访问共享资源的时候,锁才会起到作用,不过这不影响咱们实现并行的逻辑~

备注:内容来源于stack exchange,提问作者hzk999

火山引擎 最新活动