linux 清理内存的c函数,c / linux无限循环应用程序:如果调用kill -9命令,则释放内存...

我在Linux中开发了一个C应用程序,其中包含无限循环while(1)。

有些指针是动态分配的,并且在无限循环下很有用,因此释放内存的唯一时间是在while(1)被ctrl-z,ctrl-c,kill -9 apppid,killall appname中断之后。

因此,我的想法是将新的处理程序与为中断事件信号分配内存的事件相关联。

void deallocatehandler(int signal){ printf("Memory Deallocation

"); exit(0);}

int main(){

signal(SIGINT, &deallocatehandler);

signal(SIGTSTP, &deallocatehandler);

signal(SIGKILL, &deallocatehandler);

while(1){

/**

Some code here

**/

}

}

如果按ctrl-c或ctrl-z,则调用了处理程序,但问题出在SIGKILL。 命令kill -9和killall不会启动处理程序。

有人知道为什么吗? 是否有纠正建议?

SIGKILL无法处理,请阅读手册。

@Stargateur那么,如果我们调用kill命令,释放内存的想法是什么?

您可以在此链接中参考问题stackoverflow.com/questions/7376228/

好吧,您不能使用SIGKILL,此信号可用于停止进程。 我们使用SIGTERM正确结束进程。

C ++的可能重复:收到SIGKILL时如何关闭TCP套接字(服务器)

即使对于除SIGKILL和SIGSTOP以外的其他信号(都无法捕获),malloc()和free()在任何信号处理程序中也不安全使用。

另外,您只能从信号处理程序安全地调用异步信号安全函数。 像malloc(),free()甚至printf()这样的函数都不是异步信号安全的,不应从信号处理程序中调用。

SIGKILL的重点是无论如何都必须终止该过程。这就是为什么不允许您处理它的原因。

在大多数情况下,您可以从SIGTERM开始,使该过程有一个很好的退出机会。当SIGTERM不起作用时,通常将SIGKILL用作最后的手段。毕竟,SIGTERM的预期行为是该过程退出。如果不是,您就知道出了点问题。

从手册

The SIGTERM signal is a generic signal used to cause program termination. Unlike SIGKILL, this signal can be blocked, handled, and ignored. It is the normal way to politely ask a program to terminate.

...

The SIGKILL signal is used to cause immediate program termination. It cannot be handled or ignored, and is therefore always fatal. It is also not possible to block this signal.

在同一文档中,您还可以阅读此有趣的内容

In fact, if SIGKILL fails to terminate a process, that by itself constitutes an operating system bug which you should report.

您无法捕获SIGKILL和SIGSTOP信号。因此,您的信号处理程序不会执行任何操作。

当您的进程收到SIGKILL时,您无能为力,更不用说清除任何内存了。

在Linux上,内存将在程序退出时清理,因此这可能不是问题。

通常,这种退出时清除是针对SIGTERM完成的。

正确的答案是不要发送SIGKILL(仅当kill本身不起作用时,才应使用kill -9)。

这不是请求进程终止自身的方法。首先发送SIGTERM,如果它不起作用,则发送SIGKILL。

您的问题提出的原因有几个。

首先,当进程终止时,释放malloc的内存。如果现代架构不能自动执行此操作,则大多数机器将完全无法使用。

其次,某些信号和某些终止过程的方式是无法捕获的。因此,对于这些,没有任何希望进行维修工作的希望。在没有太多清理的情况下终止执行的方法中有一些信号,abort,quick_exit,_Exit。

第三,使用信号处理程序进行清理工作是完全过分的了。 C库具有为此目的而设计的atexit和at_quick_exit(自C11起)处理程序。因此,如果在执行终止时必须执行一些特殊的操作(例如,向套接字写入一些最终消息,清理文件或共享内存),请使用为此目的而设计的工具。

我从您的答案中学到了atexit和at_quick_exit函数对我来说是新的东西,谢谢:)

So the idea is that I associate new handler that deallocates memory to the interruption events signals.

没有必要!进程终止后,无论是什么原因,所有内存都会从内核中释放。因此,您无需手动执行此操作。

使用IPC资源和信号量,您将遇到无法完全解决的问题。

我的意思是用malloc或calloc动态分配的内存。它必须由free释放。如果我们不在应用程序中取消分配它,那么我们将产生垃圾。

@KallelOmar:否,进程终止后,将释放动态分配的内存。只需分配大量数据并终止您的过程,然后重复该过程1000次即可。您根本不会用完内存,因为内核可以完成这项工作!

多数民众赞成为什么我想添加句柄到相应的信号,以释放之前退出动态分配的内存

再次:你不能! kill -9终止进程,没有处理程序被调用!而且,由于内核释放了内存资源,因此不需要处理程序。再说一遍:在使用IPC资源或其他资源时,您的系统保留了这些资源,因此您必须在应用程序之外处理该问题。

内核可以纠正内存泄漏吗?

@KallelOmar:为什么您不会阅读我的答案?我说:内核将释放您的资源。不管它如何工作。所以就算了!该过程终止后,将不会有任何内存泄漏。

man 7 signal

当您对一个进程进行SIGKILL时,您不会要求它很好地终止。您要求内核停止对该进程的任何进一步执行。

因此,该进程无法知道它已收到SIGKILL。

但这对您来说并不重要,因为只有在SIGTERM未显示成功时才发出SIGKILL。

man 7 signal将显示

SIGKILL       9       Term    Kill signal

这意味着,当此信号出现时,您将不再对代码进行控制。

引用signal的定义手册:

The signals SIGKILL and SIGSTOP cannot be caught, blocked, or ignored.

从定义上讲,您无法捉住SIGKILL(杀死-9)。这是杀死进程的"最后手段",因此,出于这个原因,进程一定不能捕获它。对于友好的终止请求,请检查SIGTERM(杀死-15或杀死没有特定值)。

但是,除非您需要执行非常具体的清理操作,否则通常不应捕获此类事件。内存将被释放,但操作系统;您的程序无需捕获信号即可释放内存。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值