当你在调用read(2)时遇到ENOBUFS / ENOMEM,你会怎么做?

时间:2016-05-22 04:27:21

标签: linux posix

如果在致电 read(2)期间收到ENOBUFSENOMEM,内核是否有可能释放资源并且将来的呼叫会成功?或者,我是否将错误视为致命错误,并开始拆解过程?

1 个答案:

答案 0 :(得分:1)

我有点不知所措,看看重试会有什么用处。

如果您在读取时返回ENOMEM,则表示内核遇到严重问题。是的,重试可能有效,但也有可能不行。如果没有,重试前等待多长时间?如果你立即重试,是什么阻止你添加另一个进行100%CPU绑定循环的进程?

就个人而言,如果我从阅读中得到这样的错误,我知道如何处理错误,我会像往常一样处理错误。如果是我肯定需要读取成功的情况,那么我将失败该程序。如果该程序是关键任务,则需要在看门狗内部运行它,无论如何都要重新启动它。

请注意,请记住,如果内核返回ENOMEM,则OOM杀手将SIGKILL发送给某人的概率不可忽略。经验表明,某人可能是你的过程。这只是退出的另一个原因,并通过监视进程的监视程序处理该退出(但请记住,如果触发了OOM杀手,监视程序也可能获得SIGKILL)。

ENOBUFS的情况并没有太大的不同。仍有“延迟多长时间”和无限循环考虑因素。在这种考虑下,OOM杀手的可能性较小,但依靠看门狗仍然是正确的道路,恕我直言。

这里的核心问题是没有read(2) 应该返回任何错误的特定情况。如果出现导致这些错误的情况,则驱动程序返回EIO同样合法。

因此,除非OP知道他的代码是为了处理而构建的,否则这些错误确实应该以相同的方式处理。

最后一个没有关于OOM杀手的事。人们有时会认为它会使他们免于挂起整个系统。事实并非如此。 OOM杀手随机杀死一个进程。确实,这个过程拥有的页面越多,被杀的人就越可能。不过,我强烈建议不要依赖这个事实。

我已经看到物理内存耗尽的情况,OOM杀手杀死了一个使用很少内存的进程,花了一些时间才找到主要罪魁祸首。我已经看到内存耗尽在内核地址空间中的情况,被杀死的用户空间进程是完全随机的。

正如我上面所说的那样,OOM杀手可能会杀死你的看门狗进程,让主要的hogger继续运行。不要依赖它来修复你的代码路径。