【问题标题】:How to free dynamic allocated variable by SIGTERM?如何通过 SIGTERM 释放动态分配的变量?
【发布时间】:2010-10-23 08:39:07
【问题描述】:

我正在编写类似这样的代码

... HEADERS ...

int *var;

void child() {
  ... //some work
  free(var);
  exit(EXIT_SUCCESSFUL);
}

int main(void) {
  ...
  //allocate variable
  var = (int *) malloc(N*sizeof(int));
  ... //work with var

  for(int i; i<PROC_COUNT; i++) {
    pid_t child = fork();
    if(pid == 0) {
      child(); //main function of new proces
      break;
    }
    elseif(pid < 0) {
      //there is enormous problem -> kill every proces
      kill(0, SIGTERM);
      waitpid(0, NULL, 0); //wait for children
      free(var);
      exit(EXIT_FAILURE);
    }

  }
  free(var);
  return EXIT_SUCCESS;
}

当进程被分叉时,所有变量也被克隆。在正常情况下,所有的 var 副本都会被释放。

如果fork() 出现错误,我会向所有创建的进程发送信号 SIGTERM。而且我需要为 SIGTERM 编写释放 var 并终止应用程序的信号处理程序。然而,free() 不是signal safe function——所以我不应该调用它。但是如何释放()该变量?

非常感谢您的回答...

编辑:valgrind 还显示仍然可以访问的变量:

==5928== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 15 from 1)
==5928== malloc/free: in use at exit: 20 bytes in 1 blocks.
==5928== malloc/free: 1 allocs, 0 frees, 20 bytes allocated.
==5928== For counts of detected errors, rerun with: -v
==5928== searching for pointers to 1 not-freed blocks.
==5928== checked 49,164 bytes.

【问题讨论】:

  • Enourmouse?那是某种大型史前啮齿动物吗? :-)
  • 对不起,在斯洛伐克有点晚了,所以我弄错了。感谢您的通知。

标签: c free signals sigterm


【解决方案1】:

我可能误解了一些东西,但是在 SIGTERM 之后,整个过程肯定会消失,带走你的变量吗?

【讨论】:

    【解决方案2】:

    我怀疑你需要这样做。任何支持 fork() 的操作系统也会在进程退出时自动从 malloc() 中释放分配,无论它是如何执行的(包括终止)。

    确实存在 C 程序不在进程中运行的环境,并且您必须非常小心在退出时留下的东西。但这些环境不是 POSIX,也不支持 fork()。就此而言,它们可能不支持信号。如果您正在为任何此类不寻常的环境写作,请检查您的文档...

    如果您想看到一个干净的 valgrind 报告,那么您可以让处理程序将一个事件粘贴到孩子的事件循环中(或设置一个标志并发布一个信号量,或其他),并将该事件作为一个干净的退出来处理。如果您的程序是一个交互式应用程序,并且您希望将用户的数据保存在 SIGTERM 上,那么您也会这样做,假设您的 UI 框架尚未将 SIGTERM 转换为您的事件。

    【讨论】:

    • 那么为什么 valgrind 显示仍然可达内存? (也许你是对的,valgrind 显示的垃圾是由错误类型的 valgrind 测量造成的)
    • valgrind 试图警告您在退出之前您还没有释放内存。之后它仍然会立即被操作系统释放。通常,来自 valgrind 的报告会让您怀疑您的程序可能丢失了内存。但是在 SIGTERM 退出的情况下,您可以忽略这一点:您知道您还没有完成正常的清理工作,因此您预计会出现“内存泄漏”的虚假声明。
    • 好的,谢谢。我想知道是否有可能纠正这个有问题的事情。非常感谢!
    • 如果您确实想要一份干净的 valgrind 报告,我添加了一个可能会有所帮助的段落。不过,这取决于您孩子的工作方式,可能麻烦多于其价值。
    【解决方案3】:

    您可以使用 exec 从 main 启动子进程,而不是直接调用 child() 函数。使用命令行参数通知子程序在 main 中完成工作。这样子进程就可以正常清理了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-13
      • 1970-01-01
      • 1970-01-01
      • 2011-03-17
      • 2015-10-14
      • 2011-08-23
      • 2018-07-29
      相关资源
      最近更新 更多