BlockingIOError 异常被忽略;我应该担心吗?

jpy*_*ams 4 python linux python-3.x python-asyncio

我正在编写一个包含 20,000 个任务的脚本,每个任务都会进行一个子进程调用和一个或两个 TCP 调用。为了使这不会花费一整天,我正在使用 Python 的新asyncio.

但是,我担心脚本运行时 Python 打印出的这些错误:

Exception ignored when trying to write to the signal wakeup fd:
BlockingIOError: [Errno 11] Resource temporarily unavailable
Run Code Online (Sandbox Code Playgroud)

它将打印一堆,但不会引发任何异常。我之前确实OSError了解Too many open files并断开了与服务器的连接,但是我使用信号量一次只允许与每个服务器建立 100 个连接,总共只有 700 个连接。

由于 Python 没有引发任何异常,因此我无法捕获错误。不过,这并不似乎影响脚本。

这些错误是我应该关注的吗? 如果是这样,我需要做什么才能摆脱它们?如果没有,我如何摆脱它们,使它们不在我的程序输出中?

另外,如果这些错误很严重,为什么 Python 会忽略它们而不是引发异常?

jpy*_*ams 5

看起来限制因素是运行大量短命的subprocesses。来自Python 错误跟踪器

“尝试写入信号唤醒 fd 时忽略异常”消息来自 Modules/signalmodule.c 中的信号处理程序。问题是 Python 获得了很多 SIGCHLD 信号(测试脚本每秒在我的计算机上创建 +300 个进程)。生产者(将信号编号写入“self”管道的信号处理程序)比消费者(BaseSelectorEventLoop._read_from_self 回调)快。

有了这个补丁,我开始收到 140 个并发进程的消息,这要好得多:-) IMO 超过 100 个并发进程是疯狂的,不要在家里这样做:-) 我的意思是生命周期很短的进程。限制是每秒 SIGCHLD 的数量,即在同一秒结束的进程数。

我更改了我的代码以限制create_subprocess_exec一次可以运行多少个es。当我低于 35 时,我不再看到错误,尽管我可能会将其设置为 20 以确保安全。你的旅费可能会改变。

async def myTask(stuff, semaphore, loop):
    with semaphore:
        process = await asyncio.create_subprocess_exec('short_program', loop=loop)

def taskRunner(stuffs):
    loop = asyncio.get_event_loop()
    semaphore = asyncio.Semaphore(20)  # limit how many can run at a time
    tasks = [
        asyncio.ensure_future(myTask(semaphore, loop))
        for i in range(20000)
    ]
    loop.run_until_complete(asyncio.gather(*tasks))
    loop.close()
Run Code Online (Sandbox Code Playgroud)

  • 也许它偏离了主题,但提醒一下,代码片段中的“asyncio.Semaphore”应该与“async with”一起使用。 (2认同)