繁体   English   中英

像std :: queue这样的c ++标准库容器是否可以保证是可重入的?

[英]Are c++ standard library containers like std::queue guaranteed to be reentrant?

我见过人们建议我应该将标准容器(例如std :: queue和std :: vector)包装在互斥锁或类似物中,如果我想使用它们的话。 我读到需要锁定多个线程访问的容器的每个单独实例,而不是每种类型或c ++标准库的任何利用。 但这假设标准容器和标准库保证可重入。

这种语言有这样的保证吗?

标准说:

除非在本标准中明确指定,否则它是实现定义的,可以递归地重新输入标准C ++库中的哪些函数。

然后它继续指定一个函数必须是可重入的,如果我正确计算它,零个案例。

如果要在这方面严格遵循标准,标准库突然变得相当有限。 大量的库函数调用用户提供的函数。 这些函数的编写者,特别是如果这些函数本身作为库发布,通常不知道它们将从何处被调用。

假设任何构造函数可以从任何标准容器的emplace_back调用,这是完全合理的; 如果用户希望消除任何不确定性,他必须避免在任何构造函数中调用emplace_back 任何复制构造函数都可以从例如vector::resizesort调用,因此无法管理向量或在复制构造函数中进行排序。 等等,随意。

这包括调用可能合理使用标准库的任何第三方组件。

所有这些限制可能意味着标准库的很大一部分根本不能用于现实世界的程序中。

更新 :这甚至没有开始考虑线程。 对于多个线程,至少处理容器和算法的函数必须是可重入的。 想象一下, std::vector::operator[]不可重入。 这意味着无法从两个不同的线程同时访问两个不同的向量! 这显然不符合标准的意图。 我知道这是你的主要兴趣。 重申,不,我不认为有重复保证; 不,我认为没有这种保证在任何方面都是合理的。 ---结束更新。

我的结论是,这可能是一种疏忽。 除非另有说明,否则该标准应强制所有标准功能必须是可重入的。

我会

  • 完全忽略任何标准函数不可重入的可能性,除非很明显该函数不能合理地重入。
  • 提出标准委员会的问题。

[答案留给历史目的,但请参阅nm的答案。 有个别功能没有要求,但一个单一的全球非要求]

是的,该标准保证了标准容器成员功能的重入。

让我来定义函数的(非)-reentrancy意味着什么。 可以在线程上调用具有良好定义的行为的可重入函数,同时它已经在该线程的调用堆栈上,即执行。 显然,只有当控制流通过函数调用临时离开可重入函数时才会发生这种情况。 如果行为没有明确定义,则该函数不可重入。

(叶函数不能说是可重入的或不可重入的,因为控制流只能通过返回留下叶函数,但这对分析并不重要)。

例:

int fac(int n) { return n==0 ? 1 : n * fac(n-1); }

fac(3)的行为是返回6,即使fac(4)正在运行。 因此, fac是可重入的。

C ++标准确实定义了标准容器的成员函数的行为。 它还定义保证此类行为的所有限制。 的标准集装箱的成员函数都没有相对于重入限制。 因此,任何限制重入的实现都是不符合要求的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM