MST

星途 面试题库

面试题:Python函数返回值在异步编程中的应用

在Python的异步编程场景下,使用asyncio库。假设有多个异步函数,每个异步函数模拟一个网络请求并返回一个JSON格式的数据(例如 {'result': 'success', 'data': [1, 2, 3]})。编写一个主异步函数,它可以并发调用这些异步函数,并对返回的数据进行统一处理:将所有返回数据中的'data'列表合并成一个大列表,并计算这个大列表中所有数字的乘积,最后返回乘积结果。请给出完整的异步函数代码,并详细解释在异步操作过程中,如何正确处理函数返回值以避免竞态条件和数据不一致问题。
14.4万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试
import asyncio


async def mock_network_request():
    await asyncio.sleep(1)  # 模拟网络请求延迟
    return {'result': 'success', 'data': [1, 2, 3]}


async def main():
    tasks = [mock_network_request() for _ in range(3)]  # 创建多个异步任务
    results = await asyncio.gather(*tasks)  # 并发执行任务并等待所有任务完成
    merged_data = []
    for result in results:
        merged_data.extend(result['data'])  # 合并所有返回数据中的'data'列表
    product = 1
    for num in merged_data:
        product *= num  # 计算大列表中所有数字的乘积
    return product


if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    result = loop.run_until_complete(main())
    print(result)

异步操作中避免竞态条件和数据不一致问题的解释

  1. 使用asyncio.gatherasyncio.gather函数用于并发运行多个协程,并返回一个由所有协程结果组成的列表。它会等待所有传入的协程都完成后才返回,这样确保了在开始处理结果之前,所有的网络请求(异步函数)都已经完成,避免了部分结果未返回就开始处理的竞态条件。
  2. 结果处理:在获取到所有任务的结果(results)后,通过遍历结果列表,依次提取每个结果中的'data'列表并进行合并。这里是顺序处理结果,不存在同时访问和修改共享数据的情况,所以不会产生数据不一致问题。
  3. 计算乘积:在合并数据后,通过顺序遍历合并后的大列表计算乘积,同样不存在竞态条件,因为计算过程是单线程顺序执行的(在事件循环的上下文内),不会有其他异步操作干扰这个计算过程。