我在处理像这样的代码

... 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()不是信号安全功能 - 所以我不应该调用它。但是如何free()那个变量?

非常感谢你的回答......

编辑: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.
有帮助吗?

解决方案

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

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

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

其他提示

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

您可以使用exec从main启动子进程,而不是直接调用child()函数。使用命令行参数通知子程序在main中执行工作。然后子进程将能够正确清理。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top