Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python异步IO不显示任何错误_Python_Exception_Queue_Python Asyncio_Aiohttp - Fatal编程技术网

Python异步IO不显示任何错误

Python异步IO不显示任何错误,python,exception,queue,python-asyncio,aiohttp,Python,Exception,Queue,Python Asyncio,Aiohttp,我试图通过使用asyncio从数千个URL获取一些数据。 以下是设计的简要概述: 使用一个生产者用一堆URL一次性填充队列 产生一群消费者 每个使用者保持从队列异步提取URL,并发送GET请求 对结果进行一些后处理 合并所有处理的结果并返回 问题:asyncio几乎从不显示任何错误,它只是静静地挂起,没有错误。我把print语句放在各处,以便自己检测问题,但没有多大帮助 根据输入URL的数量和使用者的数量或限制,我可能会出现以下错误: 任务已销毁,但它处于挂起状态 任务异常从未被检索到:问题是您

我试图通过使用asyncio从数千个URL获取一些数据。 以下是设计的简要概述:

  • 使用一个
    生产者用一堆URL一次性填充
    队列
  • 产生一群
    消费者
  • 每个
    使用者
    保持从
    队列
    异步提取URL,并发送
    GET
    请求
  • 对结果进行一些后处理
  • 合并所有处理的结果并返回
  • 问题:
    asyncio
    几乎从不显示任何错误,它只是静静地挂起,没有错误。我把
    print
    语句放在各处,以便自己检测问题,但没有多大帮助

    根据输入URL的数量和使用者的数量或限制,我可能会出现以下错误:

  • 任务已销毁,但它处于挂起状态

  • 任务异常从未被检索到:问题是您的
    使用者只捕获两个非常特定的异常,并且在它们的情况下将任务标记为已完成。如果发生任何其他异常,例如与网络相关的异常,它将终止使用者。但是,
    run
    没有检测到这一点,它正在等待
    queue.join()
    ,消费者(有效地)在后台运行。这就是为什么您的程序挂起-队列中的项目永远不会被考虑,队列也永远不会被完全处理

    有两种方法可以解决这个问题,这取决于您希望程序在遇到意外异常时执行的操作。如果希望它继续运行,可以向使用者添加一个catch all
    except
    子句,例如:

    例外情况除外,如e
    打印('其他错误',e)
    queue.task_done()
    
    另一种方法是将未处理的使用者异常传播到
    run
    。这必须明确安排,但其优点是永远不允许异常以静默方式传递。(有关该主题的详细说明,请参阅。)实现此功能的一种方法是等待
    queue.join()
    同时等待消费者;由于使用者处于无限循环中,因此只有在出现异常时,才会完成

    print(“[加入队列]”)
    #等待'queue.join()`完成或消费者提出请求
    完成,u=wait asyncio.wait([queue.join(),*consumers],
    返回(当=asyncio.FIRST\u完成时)
    consumers\u raised=设置(完成)和设置(使用者)
    如果消费者提出:
    wait consumers_raised.pop()#传播异常
    
    问题:如何在asyncio中检测和处理异常

    异常通过
    wait
    传播,通常像在任何其他代码中一样被检测和处理。特殊处理仅用于捕获从“后台”任务(如
    使用者
    )泄漏的异常

    如何在不中断队列的情况下重试


    您可以调用
    wait queue.put((i,url))
    块中,除了
    之外。该项目将添加到队列的后面,由消费者拾取。在这种情况下,您只需要第一个代码片段,不想费心尝试将
    消费者
    中的异常传播到
    运行

    谢谢您提供了如此清晰、彻底的答案。在阅读您的答案之前,我做了以下操作来解决我提到的问题:1)为了重试,我在
    while
    循环中添加了
    For
    循环。2) 我还在
    get\u video\u title
    功能中添加了一个
    KeyError
    异常3)我降低了消费者的最大数量并限制了TCP连接的最大数量4)我在
    get
    请求中将
    raise\u的状态设置为
    False
    。总之,它解决了所有问题,我能够在一分钟多一点的时间内处理1000个URL。任务管理器显示瓶颈是我的wi-fi速度