Ale*_*lex 4 c++ multithreading const thread-safety c++11
根据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方法调用const方法,否则可能会减慢它们的速度).
所以,我的问题是:如果我们所有的类都必须在C++中这样(至少可以被STL使用),这是否会导致过度的同步措施?
谢谢
编辑:一些澄清:
似乎在C++ 11中,除非其const成员函数在内部同步(或不执行任何写入),否则不能将类与标准库一起使用.
虽然C++ 11本身不会自动添加任何同步代码,但是符合标准库的类不需要在C++ 98中进行同步,但在C++ 11中需要它.因此,在C++ 98中,您可以避免对可变成员进行任何内部同步,但在C++ 11中则不能.
Jon*_*ely 10
在C++ 11中,对该对象的任何const成员函数调用也将调用内部同步
为什么?这种同步不只是神奇地出现在课堂上,只有在有人明确添加时才会出现.
因此,对此对象进行单个const函数调用将花费2次锁定/解锁操作
只有当某人添加了一个内部互斥锁并且你还使用了一个外部互斥锁...但是为什么你会这样做呢?
请注意,仍然需要全局互斥锁,因为const似乎对编写器没有任何作用(除非其中一个非const方法调用const方法,否则可能会减慢它们的速度).
如果类具有用于使const成员线程安全的内部互斥锁,那么它也可以用于非const成员.如果类没有内部互斥,那么情况与C++ 98相同.
我认为你看到的是一个不存在的问题.
Herb的"const的新含义"不是由语言或编译器强制执行的,它只是设计指导,即良好代码的习惯用语.要遵循该指导,您不要向每个类添加互斥锁,以便const允许mutable成员修改成员,避免使用可变成员! 在绝对必须拥有可变成员的极少数情况下,要么要求用户自己进行锁定(并明确将该类记录为需要外部同步),要么添加内部同步并支付额外费用......但这些情况应该很少见,因此,"C++ 11对象由于新的const而变慢"并非如此,因为大多数精心设计的对象无论如何都没有可变成员.
是的,你是绝对正确的.您应该使对象遵循这些准则,因此在C++ 11中访问它们可能会更慢.如果且仅当:
该类具有mutable成员const函数修改的成员.
正在从多个线程访问该对象.
如果你确保其中至少有一个是不真实的,那么没有任何改变.从多个线程访问的对象数应始终尽可能小.并且具有可变成员的类的数量应该是最小的.所以你在谈论一组最小的对象.
即便如此......所需要的只是数据竞赛不会被打破.根据可变数据的含义,这可能只是一个原子访问.
我没有在这里看到问题.很少有标准库对象具有可变成员.我也不怕你找到一个合理的实现basic_string,vector,map等需要可变成员.
似乎在C++ 11中,除非其const成员函数在内部同步(或不执行任何写入),否则不能将类与标准库一起使用.
这是不正确的.你当然可以.你不能做的是尝试以对那些可变成员"执行任何写入"的方式跨多个线程访问该类.如果您从未以特定方式跨线程通过该C++ 11类访问该对象,那么您没问题.
所以是的,你可以使用它们.但是你只能得到自己班级提供的保证.如果你以不合理的方式通过标准库类使用你的类(比如你的const成员函数没有const或正确同步),那那就是你的错,而不是库的错.
因此,在C++ 98中,您可以避免对可变成员进行任何内部同步,但在C++ 11中则不能.
这就像说你可以逃离罗马帝国的计算机犯罪.当然可以.他们当时没有电脑 ; 所以他们不知道计算机犯罪是什么.
C++ 98/03没有"线程化"的概念.因此,标准没有"内部同步"的概念,所以你能够或不能"逃避"既没有定义也没有定义.提出标准问题比询问Ceaser当天的黑客法律是没有意义的.
现在C++ 11实际上定义了这个概念和竞争条件的概念,C++ 11能够说明何时可以"逃避不进行任何内部同步".
或者,换句话说,这就是两个标准如何回答你的问题:mutable当通过const标准库中声明的成员函数访问成员时,潜在的数据竞争结果是什么?
C++ 11:当const函数访问时,任何内部成员都不会有数据争用.此类函数的所有标准库实现必须以不会发生数据争用的方式实现.
C++ 98/03:什么是数据竞争?
| 归档时间: |
|
| 查看次数: |
619 次 |
| 最近记录: |