繁体   English   中英

关键部分和C ++中的引用返回值

[英]Critical Sections and return value by reference in C++

我已经在2012年问过一个非常类似的问题。

C ++中的关键节和返回值

我也想安全地访问容器线程,而是通过引用返回缓存的版本。

struct Container {
  const Data& getSomeData() const {
    EnterCriticalSection(& myCritSec);
    if (update) {
      cache.calulatefromcontainer();        
    }
    // fill retobj with data from structure
    LeaveCriticalSection(& myCritSec);
    return cache;
  }

 private:
  mutable Data cache;
};

问题是,“返回缓存”行不再受保护。 是否可以通过引用安全地返回“缓存”线程?

您必须考虑关键部分实际上在保护什么。

在您的代码中, myCritSec正在保护容器。 但值得注意的是,它不能保护cache成员变量。 那不是因为return cache; 行,但是因为您正在返回对其的引用,所以它可以不受客户端代码的限制而被使用,而其他线程再次调用getSomeData()并对其进行修改。

一种解决方案是返回数据的副本。

另一个解决方案是,每个可用于从Data获取信息的公共函数都将以某种方式使用父容器的myCritSec 这种方法的问题在于,参加比赛非常容易。 例如:

class Data
{
public:
     int getA() const
     {
         int res;
         EnterCriticalSection(parentCS);
         res = getAunlocked();
         LeaveCriticalSection(parentCS);
         return res;
     }
     int getB() const
     {
         int res;
         EnterCriticalSection(parentCS);
         res = getBunlocked();
         LeaveCriticalSection(parentCS);
         return res;
     }
};

然后在用户代码中:

const Data &data = container.getSomeData();
if (data.getA() == data.getB()) // <--- RACE!!!
{
}

由于对getA()getB()的调用分别是锁定和解锁CS,因此另一个线程可能会在两者之间修改数据并创建竞争条件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM