在 C 中使用信号时,使用 free()
动态分配数据的正确方法是什么?
Here有一个共享内存的例子,使用的解决方案是声明全局变量,但似乎不是很干净和安全。
这是一个示例代码,其中包含一个动态分配的结构数组,但未正确清理
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
typedef struct {
int val;
} mystruct_t;
void sigquit(int sig) {
signal(sig, SIG_IGN);
printf("Child killed\n");
// Clear the dynamic allocated data inside
// the signal quit method
//
// int i;
// for (i = 0; i < n; i++) {
// free(struct_a[i]);
// }
// free(struct_a);
exit(0);
}
int
main()
{
int n = 10;
/* dynamic allocated array of structure */
mystruct_t **struct_a = generatearray(n);
pid_t pid = fork();
if (pid == 0) {
printf("Child process. My pid is %d and my parent's id is %d.\n",
getpid(), getppid());
if (signal(SIGQUIT, sigquit) == SIG_ERR) {
printf("SIGINT install error\n");
exit(1);
}
while(1);
}
else {
printf("Parent process. My pid is %d and my parent's id is %d.\n",
getpid(), pid);
sleep(1);
kill(pid, SIGQUIT);
sleep(5);
}
return 0;
}
你会用什么方法来解决这个问题?
最佳答案
根据 POSIX,malloc()
和 free()
以及任何其他高级内存分配函数都不是信号安全的(mmap( )
和 friend 们虽然)。您不能在信号处理程序中安全地调用它们,因为它们不需要在被信号处理程序调用时继续存在。
典型的解决方法是在信号处理程序中设置一个标志,指示应清除内存。程序的主循环会定期检查此标志,并在发现已设置标志时执行所需的操作。为该变量使用类型 sig_atomic_t
并将其声明为 volatile
以获得最大的安全性。
关于用信号清除动态分配的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34445242/