锁定互斥锁只返回一个值是明智的吗?

时间:2014-08-17 18:31:52

标签: c++ multithreading thread-safety mutex

class Foo {
public:
    // ...
    const int &getBar() const noexcept;

    void doSomethingWithBar(); // (2)

private:
    std::mutex barMutex;
    int bar = 7;
};

const int &Foo::getBar() const noexcept {
    std::lock_guard<std::mutex> lock(this->barMutex); // (1)
    return this->bar;
}

void Foo::doSomethingWithBar() {
    std::lock_guard<std::mutex> lock(this->barMutex); // necessary here
    this->bar++;
}

就线程安全而言,行1是必要的,考虑到另一个线程可能会干扰并调用行2中的函数,从而更改bar的值?

请注意int可能是此处的任何类型。

2 个答案:

答案 0 :(得分:4)

看到你正在返回一个引用,在这种情况下,锁定对你来说完全没用。当您使用返回的引用时,您可能需要锁定。

但是,如果您返回的值会产生更多影响,请查看this以获取撕裂的示例。

答案 1 :(得分:0)

第1行没有您期望的效果:显然,您尝试锁定对象并在调用者处理返回的引用时将其锁定。

但是你创建的lock_gard是getBar()的本地对象,并在你返回时获得destroyed,从而解锁你刚刚获得的锁。

有几种替代方案,例如:

  • 您可以更改函数以返回bar的值,但要考虑到此值是一个快照,当您使用它时可以过时。

  • 您也可以更改功能以一次性获取和处理条形图(例如,通过提供函数作为参数)。

  • 您还可以将锁作为类成员进行管理,并提供函数releaseBar()以在不再需要时立即解锁互斥锁。然而,这是一种更危险的方法,因为呼叫者可能忘记释放锁定。