c++ - 由于新的 const,C++11 对象在多线程环境中可能会变慢吗?

标签 c++ multithreading c++11 thread-safety constants

根据 Herb Sutter ( http://isocpp.org/blog/2012/12/you-dont-know-const-and-mutable-herb-sutter ),在 C++11 中,const 方法不得按位更改对象,或者如果它们具有可变数据成员,则必须执行内部同步(例如使用互斥锁)。

假设我有一个从多个线程访问的全局对象,并且假设它有可变成员。为了便于讨论,假设我们无法修改类的源代码(它由第三方提供)。

在 C++98 中,这些线程将使用全局互斥锁来同步对此对象的访问。因此,访问将需要单个互斥锁锁定/解锁。

但是,在 C++11 中,对该对象的任何 const 成员函数调用也将调用内部同步,因此潜在地,对该对象的单个 const 函数调用将花费 2 次锁定/解锁操作(或更多,具体取决于你从一个线程调用了多少函数)。请注意,仍然需要全局互斥锁,因为 const 似乎对编写器没有任何作用(除了可能减慢它们的速度,如果其中一个非常量方法调用 const 方法)。

所以,我的问题是:如果我们所有的类在 C++ 中都必须采用这种方式(至少要被 STL 使用),这不会导致过度的同步措施吗?

谢谢

编辑:一些说明:

  1. 似乎在 C++11 中,您不能将类与标准库一起使用,除非其 const 成员函数在内部同步(或不执行任何写入)。

  2. 虽然 C++11 本身不会自动添加任何同步代码,但符合标准库的类在 C++98 中不需要同步,但在 C++11 中需要同步。因此,在 C++98 中,您可以不对可变成员进行任何内部同步,但在 C++11 中则不行。

最佳答案

in C++11, any const member function call on this object will invoke internal synchronization as well

为什么?这种同步不仅会神奇地出现在类中,而且只有在有人明确添加它时才会出现。

so potentially, a single const function call on this object will cost 2 lock/unlock operations

只有当有人向它添加了一个内部互斥量时,并且您还使用了一个外部互斥量...但是您到底为什么要这样做呢?

Note that the global mutex is still needed, because const doesn't seem to do anything for writers (except possibly slowing them down as well, if one of the non-const methods calls a const method).

如果该类具有用于使 const 成员线程安全的内部互斥锁,那么它也可以用于非 const 成员。如果该类没有内部互斥锁,则情况与 C++98 相同。

我认为您遇到了一个不存在的问题。

Herb 的“const 的新含义”不是由语言或编译器强制执行的,它只是设计指南,即好的代码的习惯用法。要遵循该指南,您不会向每个类添加互斥体,因此允许 const 成员修改 mutable 成员,您避免使用可变成员!在极少数情况下,您绝对必须具有可变成员,要么要求用户进行自己的锁定(并明确记录该类需要外部同步),要么添加内部同步并支付额外费用......但这些情况应该很少见,所以“C++11 对象因为新的 const 而变慢”是不正确的,因为大多数设计良好的对象无论如何都没有可变成员。

关于c++ - 由于新的 const,C++11 对象在多线程环境中可能会变慢吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16992575/

相关文章:

c++ - 如何将 std::bind 与标准库一起使用并保存返回类型?

c++ - ZeroMQ:带有大消息的 REQ/REP

c++ - 为什么 A/<constant-int> 在 A 无符号与有符号时更快?

c# - 通过使用任务加快处理改进

java - Java多线程-运行线程仅按顺序运行方法一次

c++ - cppreference 中对宽松排序的解释是错误的吗?

c++ - std::make_signed 接受浮点类型

c++ - OpenCV 中 VideoCapture 对象的状态

c++ - 传递 std::shared_ptr 作为对 lambda 捕获列表的引用 (C++)

c++ - boost::thread 是线程安全的吗?