加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

释放C资源和fork-exec?

发布时间:2020-12-13 18:54:27 所属栏目:Linux 来源:网络整理
导读:我正在尝试使用fork-exec从我的C -project中生成一个新进程.我正在使用fork-exec来创建子进程的双向管道.但是我担心分叉进程中的资源不会被正确释放,因为exec-call将完全接管我的进程并且不会调用任何析构函数. 我尝试通过抛出异常并在main的末尾从catch块调

我正在尝试使用fork-exec从我的C -project中生成一个新进程.我正在使用fork-exec来创建子进程的双向管道.但是我担心分叉进程中的资源不会被正确释放,因为exec-call将完全接管我的进程并且不会调用任何析构函数.

我尝试通过抛出异常并在main的末尾从catch块调用execl来绕过这个,但是这个解决方案并没有破坏任何单例.

有没有明智的方法来安全地实现这一目标? (希望避免任何atExit黑客攻击)

例如:以下代码输出:

We are the child,gogo!
Parent proc,do nothing
Destroying object

即使分叉进程也有一个单例的副本,在我调用execl之前需要对其进行破坏.

#include 
最佳答案
有很好的几率你不需要在fork和exec之间调用任何析构函数.是的,fork会复制整个进程状态,包括具有析构函数的对象,exec会删除所有状态.但它真的重要吗?来自程序外部的观察者 – 在同一台计算机上运行的另一个不相关的进程 – 可以告诉那些析构函数不会在孩子身上运行吗?如果无法辨别,则无需运行它们.

即使外部观察者可以说,在孩子身上运行析构函数也可能是错误的.通常的例子是:假设你在调用fork之前向stdout写了一些东西,但是它在库中被缓存了,所以实际上还没有被传递到操作系统.在这种情况下,你不能在孩子的stdout上调用fclose或fflush,否则输出会发生两次! (这也是为什么你几乎肯定应该调用_exit而不是退出,如果exec失败.)

说了这么多,有两种常见的情况,你可能需要在孩子身上做一些清理工作.一个是文件描述符(不要将它们与stdio FILE或iostream对象混淆),这些描述符不应该在exec之后打开.处理这些问题的正确方法是在打开它们之后尽快设置FD_CLOEXEC标志(某些操作系统允许您在打开时自行执行此操作,但这不是通用的)和/或从3循环到某些大型在孩子中呼叫关闭(不是fclose)的号码. (FreeBSD有closefrom,但就我所知,没有其他人这样做,这是一种耻辱,因为它非常方便.)

另一种情况是系统全局线程锁定 – 这是一个棘手且标准化程度较低的区域 – 可能会被父级和子级所占用,然后跨越exec继承到一个不知道它持有锁的进程.这就是pthread_atfork应该用于的内容,但我已经读到,在实践中它不能可靠地工作.我能提供的唯一建议就是“当你打电话给叉子时不要拿任何锁”,对不起.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读