如何通过 SIGTERM 释放动态分配的变量?

发布于 2024-07-18 20:05:25 字数 1282 浏览 12 评论 0原文

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

... 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.

I work on code something like this

... 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;
}

When process is forked, all variables are cloned too. In regular case all copies of var are freed.

If there is error by fork(), I send signal SIGTERM to all created processes. And I need to write signal handler for SIGTERM which free var and terminate application. However, free() is not signal safe function -- so I shouldn`t call it. But how to free() that variable?

A lot of thanks for your answers...

EDIT: valgrind also shows still reacheable variable:

==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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

止于盛夏 2024-07-25 20:05:25

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

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

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

I doubt that you need to. Any OS which supports fork(), will also automatically free allocations from malloc() when a process exits, regardless of how it does so (including termination).

There do exist environments where C programs don't run in processes, and where you have to be very careful what you leave lying around at exit. But those environments aren't POSIX, and won't support fork(). They might not support signals, for that matter. If you're writing for any such unusual environment, check your documentation...

If you want to see a clean valgrind report, then you could have the handler stick an event into the child's event loop (or set a flag and post a semaphore, or whatever), and process the event as a clean exit. That's also what you'd do if your program was an interactive application and you wanted to save the user's data on a SIGTERM, assuming your UI framework didn't already translate SIGTERM into an event for you.

疯到世界奔溃 2024-07-25 20:05:25

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

I may be misunderstanding something, but surely after SIGTERM the whole process will disappear, taking your variable with it?

始于初秋 2024-07-25 20:05:25

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

You could use exec to start the child process from main rather than calling the child() function directly. Use a command line argument to notify the child program to do the work in main. Then the child process will be able to cleanup properly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文