You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++17标准可递归重入类型函数及重入代码合规性问询

C++17中递归重入的标准规定与问题解答

先给大家铺垫下背景:在C14以及当时的现行工作草案里,标准有这么个规定——除了标准明确指定的情况外,C标准库中哪些函数允许递归重入是实现定义的。我翻遍了标准内容,除了std::recursive_mutex之外,没找到其他被明确标注可以安全递归重入的类型或函数;哪怕是std::recursive_mutex,标准也特意说明了:单个线程能获取它的所有权层数是没有硬性规定的。

针对C++17版本,咱们来逐个解答提出的问题:

问题1:C++标准定义的哪些类型或函数必须实现为可递归重入?

在C++17的标准里,依然只有std::recursive_mutex是被明确要求支持安全递归重入的类型——单个线程可以多次获取它的所有权,不会触发死锁。除此之外,标准里没有任何其他强制要求必须实现为可递归重入的标准库类型或函数。所有其他标准库组件的递归重入能力,都属于实现定义的范畴,简单说就是不同编译器、不同标准库实现可能有不一样的行为,你不能跨平台依赖这一点。

问题2:考虑到重入代码不得调用非重入函数(详见下方重入规则),是否可总结为:仅当不使用任何C标准类型或函数时,C代码才能安全重入?

这个结论太绝对了,不能这么说。首先得先把重入性和线程安全性的关系掰扯清楚:

在计算领域,若计算机程序或子程序的多次调用可在单处理器系统中安全并发执行,即该重入过程可在执行中途被中断,并在之前的调用完成前被安全再次调用(“重入”),则称其为重入的。中断可由跳转、调用等内部操作,或中断、信号等外部操作引发;这与递归不同,递归的新调用仅由内部调用触发。该重入定义与多线程环境中的线程安全性定义不同。反之,线程安全的代码不一定必须是可重入的。

再明确下重入代码必须遵守的规则:

  • 不得持有任何静态或全局非常量数据
  • 不得修改自身代码
  • 不得调用非重入的程序或例程

回到问题本身:
虽然大部分标准库函数的重入性是实现定义的,但如果你能确保自己调用的标准库组件在当前实现下是可重入的,同时你的代码本身严格遵守重入规则,那依然可以写出安全重入的C++代码。举两个例子:

  • 很多纯算法类的标准库函数,比如std::sort,如果它处理的迭代器不涉及全局状态,并且迭代器本身是重入安全的,那它大概率是可重入的——当然这还是要看具体实现,但这类场景是可以验证后使用的
  • 如果你明确使用std::recursive_mutex这类被标准保证可重入的组件,并且正确使用它,也不会破坏代码的重入性

不过要提醒一句:因为除了std::recursive_mutex之外,没有其他强制要求,所以跨平台的安全重入代码确实要格外谨慎,尽量避免依赖标准库的重入性,除非你针对特定实现做了充分验证。但绝对不是“必须完全不使用标准库”才能写出安全重入的代码。


内容的提问来源于stack exchange,提问作者Sonic78

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 18:28:11