CSc*_*ulz 1 c memory-management sigint
我有一个简单的程序,使用select和类似的东西多路复用IO.
为了中断"服务器"进程,我集成了一个对SIGINT做出反应的sig_handler .
每次分配内存时,contains方法都会执行free本身或调用方法.
使用valgrind显示,有一些分配没有被释放.
也许没有必要,但我想了解处理信号的最佳方法.按STRG + C
似乎free不会调用调用.
因此,使用中断条件退出循环将是毫无意义的,这是我的第一种方法.
在关闭整个程序之前,有没有可能清理所有东西?
感谢任何提示和建议.
Valgrind只是一个寻找内存泄漏的工具,而不是一个必须注意其建议的oracle.制作一个程序"Valgrind-clean"是一个有价值的目标,但不要让它失控.问自己一些关于该计划的问题.
方案是否需要在接收到做任何事情SIGINT或SIGQUIT或什么?是否需要进行某种干净的关机?例如,服务器可能决定完成处理所有打开的请求,或者至少向连接的客户端发送关闭消息.
突然终止是否总是留下某些块?然后你就可以从Valgrind中撤消这些报告,而不必花费额外的时间来释放已经被释放的内存.
简单来说,只有两个理由来调用free即将退出的程序.
如果这是撤消Valgrind消息的最简单方法(也就是说,没有阅读Valgrind手册)
如果它使你的代码更简单.
否则,只是free在程序退出期间不要调用,因为它只会烧掉CPU周期.
处理SIGINT:我可以想到处理SIGINT的四种常用方法:
使用默认处理程序.强烈建议,这需要最少量的代码,不太可能导致任何异常的程序行为.你的程序将退出.
用于longjmp立即退出.这适合喜欢骑无头盔的快速摩托车的人.这就像用图书馆电话玩俄罗斯轮盘赌.不建议.
设置一个标志,并中断主循环的pselect/ ppoll.这是一个很难做到的痛苦,因为你必须扭动信号面具.你想要中断pselect/ ppoll只是,而不是像malloc或那样的非重入函数free,所以你必须非常小心信号掩码之类的东西.不建议.您必须使用pselect/ ppoll而不是select/ poll,因为"p"版本可以原子设置信号掩码.如果您使用select或poll,在您检查标志之后但在致电select/ 之前信号可能会到达poll,这很糟糕.
创建一个管道以在主线程和信号处理程序之间进行通信.始终在select/ 的调用中包含此管道poll.信号处理程序只是将一个字节写入管道,如果主循环成功从另一端读取一个字节,则它会干净地退出.强烈推荐.您也可以让信号处理程序自行卸载,因此不耐烦的用户可以点击CTRL+C两次以立即退出.
两种最简单,最简单的方法是#1和#4.
退出的程序没有任何泄漏. 只有正在运行的程序才会出现泄漏.一旦程序退出,所有内存都被释放(因此不再有泄漏).