Как использовать lock_guard при возврате защищенных данных - PullRequest
20 голосов
/ 04 октября 2010

У меня есть вопрос, касающийся использования boost::lock_guard (или аналогичных блокировок области действия) и использования переменных, которые должны быть защищены блокировкой в ​​выражении return.

Каков порядок уничтожения локальных объектов и копирования возвращаемого значения? Как на это влияет оптимизация возвращаемого значения?

Пример:

Data Class::GetData()
{
    boost::lock_guard<boost::mutex> lock(this->mMutex);
    return this->mData;
}

Было бы это правильно (если mData - переменная, защищенная mMutex)? Или мне придется использовать локальную область и временную область, как показано в примере ниже:

Data Class::GetData()
{
    Data ret;
    {
        boost::lock_guard<boost::mutex> lock(this->mMutex);
        ret = this->mData;
    }
    return ret;
}

Ответы [ 3 ]

23 голосов
/ 04 октября 2010

Просто прямой возврат, как в первом примере, верен.Возвращаемое значение создается до уничтожения локальных переменных и, следовательно, до снятия блокировки.

3 голосов
/ 04 октября 2010

Каков порядок уничтожения локальных объектов и копирования возвращаемого значения?

Как правило, объекты стека уничтожаются в обратном порядке создания. Как указывалось ранее, оба указанных вами подхода обеспечат желаемое поведение.

Как на это влияет оптимизация возвращаемого значения?

RVO здесь не должен беспокоить - все, что он делает, это создает выходной объект непосредственно в буфере стекового фрейма - избегая затрат на создание именованного временного объекта (как в вашем втором примере выше) Это делается перед вызовом локальных деструкторов.

Лучше всего использовать код из примера 1 выше.

0 голосов
/ 04 октября 2010

Обе части эквивалентны. Фактически для случая № 1 - компилятор C ++ создаст структуру, описанную в случае № 2. Так что № 1 предпочтительнее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...