atexit是否有害?

5

在诸如库之类的大型项目中使用atexit存在固有的风险吗?

如果是这样,那么与atexit背后的技术性质有何关系可能会导致在较大项目中出现问题?

2个回答

7
我避免在库中使用 atexit 的主要原因是任何使用它都会涉及全局状态。一个好的库应该避免拥有全局状态。
然而,还有其他技术原因:
  1. 实现只需要支持少量 (我想是32个) 的 atexit 处理器。超过这个数量后,所有对 atexit 的调用可能失败,或者成功或失败取决于资源可用性。因此,你必须处理如果无法注册你的 atexit 处理器时该怎么办,并且可能没有好的方法来继续执行。

  2. atexitdlopen 或其他动态加载库的方法的交互未被定义。已注册 atexit 处理器的库不能安全地被卸载,不同实现处理这种情况的方式可能会有所不同。

  3. 编写不良的 atexit 处理器可能会相互影响,或者只是产生糟糕的行为,从而阻止程序正确退出。例如,如果一个 atexit 处理器试图获取在另一个线程中持有的锁,并且由于在调用 exit 时的状态而无法释放该锁。


1
自从glibc 2.2.3版本以来,可以在共享库中使用atexit()(和on_exit(3))来建立在共享库卸载时调用的函数。 然而,我不确定其他C库是否强制执行相同的行为。因此,如果您仅针对glibc,则不适用于您。 - Julian Kirsch

1

那么,当传递给 atexit 的函数有可能调用 exit 或者不正常返回时,通常会出现问题? - Vilhelm Gray
这个 bug 的 C++ 等效版本实际上存在于 LLVM 代码库的某个地方(我忘记在哪里了)。他们有一个调用 exit 的析构函数... - R.. GitHub STOP HELPING ICE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接