多线程C应用程序应如何处理失败的malloc()?

ipa*_*ola 9 c malloc pthreads

我正在处理的应用程序的一部分是一个简单的基于pthread的服务器,它通过TCP/IP套接字进行通信.我在C中编写它是因为它将在内存受限的环境中运行.我的问题是:如果其中一个线程遇到返回NULL的malloc(),程序应该怎么做?到目前为止我想出的可能性:

  1. 没有特别处理.让malloc()返回NULL并让它被解除引用,以便整个事件发生段错误.
  2. 通过调用abort()或exit(-1)立即退出失败的malloc().假设环境将清理一切.
  3. 跳出主事件循环并尝试pthread_join()所有线程,然后关闭.

第一种选择显然是最简单的,但似乎非常错误.第二个也似乎错了,因为我不确切知道会发生什么.第三个选项,似乎除了两个问题诱人的:首先,所有的线程不需要在正常情况下和第二连接回主线程,以完成该线程执行,其余大部分线程必须调用malloc( )无论如何.

我该怎么办?

小智 4

这是space/rad硬系统普遍禁止动态内存分配的原因之一。当malloc()失败时,“治愈”失败是极其困难的。你确实有一些选择:

  • 您不需要使用内置的 libc malloc()(根本不需要,或者像往常一样)。您可以包装 malloc()以在失败时执行额外的工作,例如通知其他内容。当使用看门狗之类的东西时,这很有用。您还可以使用成熟的垃圾收集器,但我不推荐它。最好是识别并修复泄漏。
  • 根据存储和复杂性,不常访问的分配块可以映射到磁盘。但在这里,通常您只会看到物理内存中几 KB 的节省。
  • 您可以使用静态内存池和您自己的内存池malloc(),但不会过度使用它。如果您已经广泛地分析了堆的使用情况(使用像 Valgrind 的Massif或类似工具),您可以合理地调整池的大小。

然而,这些建议中的大多数都归结为malloc()如果失败不是一种选择,那么就不信任/使用该系统。

就您而言,我认为您能做的最好的事情就是确保发生故障时通知看门狗malloc(),以便您的进程(或整个系统)可以重新启动。您不希望它在陷入僵局时看起来“活着并且正在运行”。这可能就像取消文件链接一样简单。

写出非常详细的日志。哪个文件/行/函数发生了故障?

如果malloc()在尝试获取几 KB 时失败,则表明您的进程确实无法可靠地继续下去。如果无法获取几百 MB,您也许可以恢复并继续。因此,您采取的任何操作都应该基于您试图获取多少内存,以及分配更小尺寸的调用是否仍然成功。

你永远不想做的一件事就是只对 NULL 指针进行操作并让它崩溃。它只是草率,没有提供任何有用的错误记录,并且给人的印象是您的软件质量低/不稳定。