可变关键字和线程安全

3

我有一个抽象基类

class Map {
  public:
    virtual Value get(Key const &) const;
};

来自外部库的数据库类

class Database {
  public:
    // logically const and thread-safe
    Value get(Key const &key);
};

我开始实现的方式如下:

class PersistentMap : public Map {
    Database db;

  public:
    Value get(Key const &key) const
    { return const_cast<Database &>(db).get(key); }
};

随着const_cast的数量不断增加,我通过向PersistentMap::db添加mutable说明符(以及一个注释来提醒自己这种做法的丑陋)来摆脱它们。

  1. 我的第一次尝试使用const_cast是否线程安全?
  2. 我的新方法是线程安全的吗,还是db也应该标记为volatile

4
“逻辑上常量”和“线程安全”有什么关联吗?const_castconstmutable是来自“类型系统”的内容,与线程安全无关。因此第一个问题没有任何意义。此外,“volatile”在多线程中没有用处,这是一个常见的误解(参见https://dev59.com/5HE95IYBdhLWcg3wDpYG)。 - GManNickG
@larsmans:优化不会破坏线程安全的代码。而且,“const”只是表示变量所表示的值不能被修改,你可以强制转换它,使其“可变”,等等。没有任何关于它影响其线程安全性的内容,运行时部分的值。 - GManNickG
@GMan:好的,我被说服了。你会把你的评论发布为答案,还是这个问题已经有人问过了,是重复的https://dev59.com/5HE95IYBdhLWcg3wDpYG? - Fred Foo
@GMan “优化不会破坏线程安全的代码。”我认为这并不正确(或者至少只是虚假的,一个使代码不再线程安全的优化意味着代码一开始就不是线程安全的)。考虑像DCLP这样的东西,它被认为是不线程安全的,但在某些架构上,如果您可以依赖编译器不“优化”您的代码,则可能是线程安全的。当然,编译器有权这样做,因为有了“as-if”规则(因为它只知道有一个线程),但我认为您可以理解我的观点。 - Logan Capaldo
@Logan:嗯,你肯定看到这里的问题了:“使代码不线程安全的优化意味着代码一开始就不是线程安全的”,因此“优化不能破坏线程安全的代码”不适用...换句话说,我说“如果代码是线程安全的,优化不会破坏它”,而你说“那是错的,除非你的意思是如果优化破坏了它,它本来就不是线程安全的。”是的,这是同样的句子,逆推法。 - GManNickG
显示剩余6条评论
1个回答

2

这完全取决于Database::get是否具有线程安全性。如果它包含锁以防止并发访问,或者以其他方式对并发访问进行了保护,则您的代码使用const_cast或mutable都是可以的。使用volatile是完全无关紧要的。


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