在SIGINT上释放已分配内存的最佳实践

CSc*_*ulz 1 c memory-management sigint

我有一个简单的程序,使用select和类似的东西多路复用IO.
为了中断"服务器"进程,我集成了一个对SIGINT做出反应的sig_handler .

每次分配内存时,contains方法都会执行free本身或调用方法.

使用valgrind显示,有一些分配没有被释放.
也许没有必要,但我想了解处理信号的最佳方法.按STRG + C
似乎free不会调用调用. 因此,使用中断条件退出循环将是毫无意义的,这是我的第一种方法.

在关闭整个程序之前,有没有可能清理所有东西?

感谢任何提示和建议.

Die*_*Epp 8

Valgrind只是一个寻找内存泄漏的工具,而不是一个必须注意其建议的oracle.制作一个程序"Valgrind-clean"是一个有价值的目标,但不要让它失控.问自己一些关于该计划的问题.

  1. 方案是否需要在接收到做任何事情SIGINTSIGQUIT或什么?是否需要进行某种干净的关机?例如,服务器可能决定完成处理所有打开的请求,或者至少向连接的客户端发送关闭消息.

  2. 突然终止是否总是留下某些块?然后你就可以从Valgrind中撤消这些报告,而不必花费额外的时间来释放已经被释放的内存.

简单来说,只有两个理由来调用free即将退出的程序.

  1. 如果这是撤消Valgrind消息的最简单方法(也就是说,没有阅读Valgrind手册)

  2. 如果它使你的代码更简单.

否则,只是free在程序退出期间不要调用,因为它只会烧掉CPU周期.

处理SIGINT:我可以想到处理SIGINT的四种常用方法:

  1. 使用默认处理程序.强烈建议,这需要最少量的代码,不太可能导致任何异常的程序行为.你的程序将退出.

  2. 用于longjmp立即退出.这适合喜欢骑无头盔的快速摩托车的人.这就像用图书馆电话玩俄罗斯轮盘赌.不建议.

  3. 设置一个标志,并中断主循环的pselect/ ppoll.这是一个很难做到的痛苦,因为你必须扭动信号面具.你想要中断pselect/ ppoll只是,而不是像malloc或那样的非重入函数free,所以你必须非常小心信号掩码之类的东西.不建议.您必须使用pselect/ ppoll而不是select/ poll,因为"p"版本可以原子设置信号掩码.如果您使用selectpoll,在您检查标志之后但在致电select/ 之前信号可能会到达poll,这很糟糕.

  4. 创建一个管道以在主线程和信号处理程序之间进行通信.始终在select/ 的调用中包含此管道poll.信号处理程序只是将一个字节写入管道,如果主循环成功从另一端读取一个字节,则它会干净地退出.强烈推荐.您也可以让信号处理程序自行卸载,因此不耐烦的用户可以点击CTRL+C两次以立即退出.

两种最简单,最简单的方法是#1和#4.

退出的程序没有任何泄漏. 只有正在运行的程序才会出现泄漏.一旦程序退出,所有内存都被释放(因此不再有泄漏).

  • "退出程序没有任何泄漏"的+1.爱它. (5认同)