Время защиты блокировки на основе области действия и возвращаемых значений

class C {
    mutable std::mutex _lock;
    map<string,string> deep_member;
public:
    auto get_big_lump()
     {
     std::unique_lock<std::mutex> lock(_lock); // establish scope guard
     return deep_member;  // copy the stuff while it can't be changed on another thread.
     }
};

Каково гарантированное время в отношении защиты и копирования возвращаемого значения? Будет ли копирование выполняться, пока удерживается блокировка, или некоторые из них могут быть выполнены после возврата из тела функции в случае разрешенных (или фактических!) оптимизаций?


person JDługosz    schedule 11.01.2016    source источник


Ответы (2)


Все деструкторы локальных объектов вызываются после завершения тела функции. Оператор return является частью тела функции, поэтому гарантируется, что блокировка будет удерживаться во время выполнения копирования.

Оптимизации не изменят этого факта, они изменят только место назначения для копии - это может быть либо промежуточное временное, либо реальное место назначения на месте вызова. Блокировка будет существовать только для первой копии, независимо от того, куда она отправляется.

Однако имейте в виду, что фактическая блокировка прицела в коде неверна. Вам нужно lock_guard - но возможно, это просто ошибка демо-копирования и вставки, а реальный код имеет настоящую защиту.

person SergeyA    schedule 11.01.2016

std::lock не устанавливает защиту области действия! Только запирает. Он не разблокируется. Вы хотите это:

std::unique_lock<std::mutex> lock(_lock);

который блокируется при строительстве и разблокируется при разрушении (что происходит при выходе из прицела).

Инициализация возвращаемого значения произойдет до того, как локальные переменные будут уничтожены и, следовательно, пока удерживается блокировка. Оптимизации компилятора не могут нарушать правильно синхронизированный код.

Однако обратите внимание, что если возвращаемое значение затем копируется или перемещается в какую-либо другую переменную, это второе копирование или перемещение произойдет после снятия блокировки.

person Brian Bi    schedule 11.01.2016
comment
Извините, это ошибка в посте. - person JDługosz; 12.01.2016
comment
@Brian Спасибо за ответ, мне тоже нужно было это знать. Знаете ли вы навскидку, какие пункты стандарта будут нарушены, если компилятор не будет реализовывать такое поведение? - person sircolinton; 08.06.2018
comment
@sircolinton О каком именно поведении вы говорите? Пожалуйста, опубликуйте новый, подробный вопрос. - person Brian Bi; 10.06.2018
comment
@Brian Поведение, описанное в вашем ответе. Я спрашивал, можете ли вы предоставить ссылки на стандарт, чтобы подтвердить свой ответ. - person sircolinton; 10.06.2018