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

时间:2021-01-24 21:16:58

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.

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

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?

如果fork()出错,我将信号SIGTERM发送到所有创建的进程。我需要为SIGTERM编写信号处理程序,它可以释放var并终止应用程序。但是,free()不是信号安全功能 - 所以我不应该调用它。但是如何free()那个变量呢?

A lot of thanks for your answers...

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

EDIT: valgrind also shows still reacheable variable:

编辑: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.

3 个解决方案

#1


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

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

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

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

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.

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

#2


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

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

#3


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.

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

#1


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

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

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

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

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.

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

#2


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

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

#3


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.

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