【问题标题】:freeing memory inside a signal handler在信号处理程序中释放内存
【发布时间】:2012-02-19 19:18:52
【问题描述】:

我正在编写一个使用套接字的 API。在 API 中,我为各种项目分配内存。我想确保关闭套接字并释放内存,以防出现 Ctrl-C 之类的信号。在对此进行研究时,似乎 free() 不在安全函数列表中(man 7 信号),因此,我无法释放信号处理程序内的内存。我可以关闭套接字就好了。有没有人对如何释放内存有任何想法?提前感谢您的宝贵时间。

【问题讨论】:

  • 添加您打算从信号中幸存吗?
  • 不,不是。我只是想在失败前清理内存和套接字

标签: c linux signals signal-handling


【解决方案1】:

不要在处理程序中释放。相反,向您的程序表明需要释放某些东西。然后,在你的程序中检测到它,这样你就可以从主上下文中解放出来,而不是信号上下文。

【讨论】:

    【解决方案2】:

    一种技术(也存在其他技术):

    1. 让您的程序运行一个主处理循环。
    2. 让您的主处理循环检查一个标志,看看它是否应该“继续运行”。
    3. 让您的信号处理程序简单地将“继续运行”标志设置为 false,而不是终止程序。
    4. 让您的主处理循环在退出之前进行内存清理。

    这样做的好处是将分配和解除分配都放在以已知顺序调用的代码块中。在处理相互关联的对象网络时,这样做可能是天赐之物,并且两个处理流之间不会出现争用条件,试图弄乱同一个对象。

    【讨论】:

    • 这是一个库 API,所以这里不适用主循环
    • 因为我正在构建一个应用程序而不是一个库,所以这个解决方案非常适合我的问题。谢谢你的回答!
    【解决方案3】:

    您是在编写库还是应用程序?如果您正在编写库,则无需安装信号处理程序,这将与调用应用程序发生冲突。如果需要,处理此类信号是应用程序的业务,然后对您的库进行适当的清理调用(从信号处理程序上下文之外)。

    当然,即使您正在编写应用程序,也没有理由处理SIGINT 来关闭套接字并释放内存。处理信号的唯一原因是您不想终止,或者您有未保存的数据或共享状态(例如共享内存或文件系统中的内容)需要在终止之前进行清理。释放内存或关闭纯粹由您自己的进程使用的文件描述符不是您在退出时需要执行的任务。

    【讨论】:

      【解决方案4】:

      或者,不要捕捉信号,而是让操作系统处理清理,因为无论如何它都会在进程清理期间执行此操作。您不会释放任何与流程没有直接关联的资源,因此没有特别需要手动释放它们。

      【讨论】:

      • 我认为你和 R 说的很有道理。首先让应用程序完成所有信号处理(更有意义)。我不确定 SIGINT 或 SIGSEGV 是否会关闭套接字。我担心他们会让它们保持打开状态,直到出现一段时间。谢谢你纠正我。
      • 我在资源泄漏方面有过一些不好的经历,因为该进程会在退出时将其清理干净。我见过一些难以解释的奇怪崩溃,如果没有其他原因:如果您不想要求任何警告(无论是来自编译器还是静态分析器),这会使构建维护更加烦人
      猜你喜欢
      • 2013-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-10
      • 2012-05-03
      • 1970-01-01
      • 2014-03-21
      • 1970-01-01
      相关资源
      最近更新 更多