Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.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
多线程C应用程序应该如何处理失败的malloc()?_C_Malloc_Pthreads - Fatal编程技术网

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

多线程C应用程序应该如何处理失败的malloc()?,c,malloc,pthreads,C,Malloc,Pthreads,我正在处理的应用程序的一部分是一个简单的基于pthread的服务器,它通过TCP/IP套接字进行通信。我用C编写它,因为它将在内存受限的环境中运行。我的问题是:如果其中一个线程遇到返回NULL的malloc(),程序应该怎么做?到目前为止,我提出了各种可能性: 没有特殊处理。让malloc()返回NULL并取消对它的引用,这样整个过程都会出错 通过调用abort()或Exit(-1)立即退出失败的malloc()。假设环境会把一切都清理干净 跳出主事件循环并尝试pthread_join()所有线

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

  • 没有特殊处理。让malloc()返回NULL并取消对它的引用,这样整个过程都会出错
  • 通过调用abort()或Exit(-1)立即退出失败的malloc()。假设环境会把一切都清理干净
  • 跳出主事件循环并尝试pthread_join()所有线程,然后关闭
  • 第一种选择显然是最简单的,但似乎非常错误。第二个似乎也错了,因为我不知道会发生什么。除了两个问题外,第三个选项似乎很诱人:第一,在正常情况下,所有线程都不需要连接回主线程;第二,为了完成线程执行,剩余的大多数线程无论如何都必须再次调用malloc()


    我该怎么办?

    选项2没有问题。您不必假设-
    exit()
    退出该进程,这意味着所有线程都被拆除,所有内容都被清理


    不要忘记尝试记录分配失败的位置。

    我认为这取决于您的体系结构

    malloc()
    失败是否意味着只有该线程无法继续,或者整个进程在这种情况下会停止


    通常,当内存非常紧张(即微处理器环境)时,最好避免所有动态内存分配,以避免类似问题。

    有第四种选择:释放一些内存(缓存总是很好的候选者),然后重试


    如果您负担不起,我会选择选项2(显然,记录或打印某种错误消息)。。。清理的唯一问题是有序地关闭打开的网络连接,以便客户端知道另一端的应用程序正在关闭,而不是发现意外的连接问题。

    这是通常禁止动态内存分配的原因之一。当
    malloc()
    失败时,很难“治愈”失败。您确实有一些选择:

    • 您不需要使用内置的libc
      malloc()
      (完全或像往常一样)。您可以在失败时做额外的工作,例如通知其他内容。这在使用看门狗之类的东西时很有用。你也可以用a,尽管我不推荐。最好是识别和修复泄漏
    • 根据存储和复杂性,不经常访问的分配块可以映射到磁盘。但在这里,您通常只看到物理内存中节省了几KB
    • 您可以使用一个静态内存池和您自己的
      malloc()
      ,这样就不会过度使用它。如果您已经广泛地分析了堆的使用情况(使用Valgrind的massif或类似工具),那么可以合理地调整池的大小
    然而,这些建议中的大多数归结起来是,如果不能选择失败,则不信任/使用系统
    malloc()

    在您的情况下,我认为您能做的最好的事情是确保在
    malloc()
    失败时通知看门狗,以便您的进程(或整个系统)可以重新启动。你不希望它在死锁状态下看起来“活跃且运行”。这可能很简单,只需取消文件链接即可

    写非常详细的日志。发生故障的文件/行/函数是什么

    如果
    malloc()
    在尝试获取几KB时失败,这是一个很好的迹象,表明您的进程确实无法可靠地继续。如果它无法捕获几百MB的数据,您可能能够恢复并继续运行。因此,无论您采取什么行动,都应该基于您试图获取的内存量,以及分配更小大小的调用是否仍然成功


    你永远不想做的一件事就是对空指针进行操作,让它崩溃。它只是草率的,没有提供有用的日志记录哪里出了问题,给人的印象是你的软件质量低/不稳定

    根据我个人的经验,我可以看出malloc故障的频率往往被高估了。例如,在Linux中,通常的“解决方案”是2的变体,并且不会出现malloc故障。一个过程突然死亡。在较大的系统上,应用程序往往会死亡,因为一旦交换使其失去响应,用户或看门狗就会杀死它


    这使得清理工作变得更加困难,也使得很难找到一个通用的解决方案

    这是在操作系统上运行的吗?pthreads的使用表明了这一点。你知道malloc()会返回NULL吗?在某些系统(例如Linux)上,故障将发生在malloc()中,并由操作系统(通过终止进程)处理,而malloc()不会返回

    我建议您在初始化应用程序时分配一个内存池,并从中分配,而不是在初始化后使用malloc()。这将使您能够控制内存分配算法以及内存耗尽时的行为。如果池内存不足,则在应用程序有机会启动它无法完成的任何操作之前,初始化时会出现单点故障

    在实时和嵌入式系统中,通常使用。如果您的操作系统不提供服务,可以通过预先分配内存块并将其指针放在队列上来实现。要分配一个块,您需要从队列中获取一个指针,要释放它,您需要将它放回队列中。当队列为空时,内存将耗尽,您可以使用baulk和处理错误,也可以使用block和wai