【发布时间】:2021-01-26 19:05:29
【问题描述】:
“神奇的静态”单例方法通常非常有效:
T& instance() {
static T inst;
return inst;
}
以线程安全的方式,它在第一次调用时创建T,并且该对象一直存在到程序关闭。但是,如果这是一个日志记录对象,并且如果有后台线程比 main 更持久,这可能会崩溃。我看到有人提到了这个问题,但没有提到解决方案:
这是一种可行的方法吗?:
/*static*/ T& T::instance() {
static auto inst = std::make_shared<T>();
static thread_local auto threadInst = inst; // Hope this call gets hit before `inst` goes out of scope.
return *threadInst;
}
据我了解,只要每个线程在 main 退出之前调用 T::instance(),该线程就会正确设置 threadInst,只要调用线程正在运行,它就会使对象保持活动状态。
问题:
- 正确吗?只要
T::instance()在main()开始之后和main()结束之前被每个线程首先调用,以上是否会避免UB? - 有没有办法放松这个限制?我不知道有。特别是,我想不出一种方法来销毁
inst与其他线程进行通信。
【问题讨论】:
-
"...如果后台线程比主线程更持久,.." 这就是问题所在。现在运行时(和操作系统卸载共享库)正在关闭并删除对仍在运行的任何线程的支持。
-
“飞行员刚跳下飞机,但我相信我们会没事的。”当你的主线程退出时会发生什么。
-
为什么不能强制
main()成为最后一个退出的线程? -
可以直接泄漏对象而不是破坏它吗?
-
如果你依赖于共享指针的引用计数,那么就让调用者自己处理它的副本。如果它实际上只是在所有线程之间共享的同一个实例,为什么还要为这个线程本地单例而烦恼呢?
标签: c++ multithreading singleton