gpt4 book ai didi

c++ - 你怎么知道 main 是否已经退出?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:23:55 31 4
gpt4 key购买 nike

在 C 和 C++ 中,atexit 函数在 exit 内部调用,或者在 main 返回后调用(名义上调用 exit : __libc_start_main(argc,argv) { __libc_constructors(); exit(main(argc,argv)); ).

有没有办法查明我们是否在退出序列内? C++ 全局和局部静态的析构函数是用 atexit 注册的,所以你的代码当然可以在这个阶段被调用。 (有趣的是,在某些平台上,如果您尝试在 exit 中创建 C++ 本地静态对象,它会在退出锁上死锁!)

到目前为止我最好的尝试如下:

static bool mainExited = false;
static void watchMain() {
static struct MainWatcher {
~MainWatcher() { mainExited = true; }
} watcher;
}

当你想观察退出时,你调用watchMain()mainExited随时告诉你退出序列是否已经开始——除了当然,如果稍后初始化的本地静态对象正在破坏!

是否可以改进技术来纠正此问题,或者是否有其他方法可行?

旁白——用例!

虽然从语言的角度来看这个问题很有趣(有点像“我可以判断我是否在 catch block 中吗?”),但概述一个用途也很有用-案件。我在编写一些代码时遇到了这个问题,这些代码将在加载和不加载 JVM 的情况下运行(直接调用或通过 JNI 调用)。 JVM 退出后,调用 C atexit 处理程序,如果类加载器未卸载 JNI 共享库,则不调用 JNI_OnUnload

由于共享库的对象可以通过显式销毁(并且应该释放它们的资源)和在退出时清理来销毁,我需要安全地区分这两种情况,因为当我们到达导出时 JVM 已经消失代码!基本上没有一点嗅探,我无法在共享库的 JNI 规范/文档中找到 JVM 是否仍然存在,如果它已经消失,那么尝试释放我们拥有的引用肯定是错误的到 Java 对象。

最佳答案

这里真正的问题是您列出的所有权语义被搞乱了。 JVM 有点拥有您的共享库,但也有点不拥有。您有一堆对 Java 对象的引用,有时您需要清理这些对象,有时则不需要。

这里真正的解决方案是不要将对 Java 对象的引用保留为全局变量。然后,无论出于何种原因卸载库时,您都不需要知道 JVM 是否仍然存在。只需在 Java 引用的对象内部保留对 Java 对象的引用,然后让 JVM 关心它是否需要释放它们。

换句话说,不要让自己一开始就负责清理退出。

关于c++ - 你怎么知道 main 是否已经退出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29005741/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com