0

假设我有以下代码:

struct Obj {
    mutable bool valueIsCached_;
    mutable int value_;
    const int parameter_;

    Obj (int parameter) : valueIsCached_ (false), parameter_ (parameter) {
    }

    int getValue () const {
        if (!valueIsCached) {
            value_ = calculateValue ();  // #1
            valueIsCached_ = true;       // #2
        }
        return value_;
    }

 private:
    int calculateValue () {
        /* calculate value based on parameter and return it;
           return value only depends on value of parameter_
           (no side effects; no dependence on global state)
        */
    }
 };

如果编译器不对标记为#1 和#2 的行重新排序,那么这段代码显然是线程安全的。可能发生的最糟糕的事情是多次计算value_. 但是,一旦我们不能保证 #2 在 #1 之后发生,代码就会变得线程不安全。

  1. 我们怎样才能避免这种情况?
  2. value_如果类型是,例如 a ,事情会变得更糟struct吗?
4

1 回答 1

1

您需要插入一个屏障。下面是 VC++ 的代码:

int getValue () const {
    if (!valueIsCached_) {
        value_ = calculateValue ();  // #1
        _WriteBarrier();             // force value_ to be written first.
        valueIsCached_ = true;       // #2
    }
    return value_;
}

请注意,这是假设calculateValue是线程安全的,因为它可以被多个线程调用,并且多次写入value_valueIsCached_安全的。

于 2012-12-03T18:08:10.267 回答