我正在编写一个包含20,000个任务的脚本,每个任务进行一个子流程调用和一个或两个TCP调用。为了不花一整天的时间,我使用了Python的新asyncio
。
但是,我担心脚本运行时Python打印出来的这些错误:
Exception ignored when trying to write to the signal wakeup fd:
BlockingIOError: [Errno 11] Resource temporarily unavailable
它将打印一堆,但不会引发任何异常。我确实收到了OSError
的{{1}}信息,并且之前与服务器的连接断开了,但是我使用了信号灯,一次只允许100个连接到每个服务器,而总共只有700个连接。
由于Python没有引发任何异常,所以我无法捕获错误。但是似乎不会影响脚本。
这些错误我应该关注吗?如果是这样,我应该怎么做才能消除它们?如果没有,我如何摆脱它们,使它们不在我程序的输出中?
此外,如果这些错误很严重,为什么Python会忽略它们而不是引发异常?
答案 0 :(得分:2)
似乎限制因素正在运行许多短命的subprocess
。来自Python bug tracker:
“试图写入信号唤醒fd时忽略异常”消息来自Modules / signalmodule.c中的信号处理程序。问题在于Python获得了很多SIGCHLD信号(测试脚本每秒在我的计算机上创建+300个进程)。生产者(将信号编号写入“ self”管道的信号处理程序)比消费者(BaseSelectorEventLoop._read_from_self回调)快。
有了补丁,我开始收到包含140个并发进程的消息,这更好:-) IMO超过100个并发进程很疯狂,请不要在家中这样做:-)我的意思是生命周期很短的进程。限制是每秒SIGCHLD的数量,因此在同一秒结束的进程数量。
我更改了代码以限制一次可以运行多少create_subprocess_exec
个代码。当我低于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()