c++ - tag - Cómo utilizar lock_guard al devolver datos protegidos
tag a domicilio (3)
Tengo una pregunta sobre el uso de boost::lock_guard
(o bloqueos de ámbito similares) y el uso de variables que deberían estar protegidas por el bloqueo en una declaración de return
.
¿Cómo es el orden de destruir objetos locales y copiar el valor de retorno? ¿Cómo afecta esto la optimización del valor de retorno?
Ejemplo:
Data Class::GetData()
{
boost::lock_guard<boost::mutex> lock(this->mMutex);
return this->mData;
}
¿Esto sería correcto (si mData es la variable protegida por mMutex)? O tendría que usar un alcance local y un temporal como el que se muestra en el siguiente ejemplo:
Data Class::GetData()
{
Data ret;
{
boost::lock_guard<boost::mutex> lock(this->mMutex);
ret = this->mData;
}
return ret;
}
¿Cómo es el orden de destruir objetos locales y copiar el valor de retorno?
Generalmente, los objetos de la pila se destruyen en orden inverso de creación. Como se indicó anteriormente, ambos enfoques que especifique proporcionarán el comportamiento deseado.
¿Cómo afecta esto la optimización del valor de retorno?
RVO no debería ser una preocupación aquí. Todo lo que hace es construir el objeto de salida directamente en el búfer del marco de la pila, evitando la sobrecarga de crear un objeto temporal con nombre (como en el segundo ejemplo anterior). Esto se hace antes de invocar a los destructores locales.
Es mejor utilizar el código del ejemplo 1 anterior.
Ambas piezas son equivalentes. De hecho, para el caso # 1, el compilador C ++ creará la estructura descrita en el caso # 2. Así que # 1 es preferible.
Solo un retorno directo como en tu primer ejemplo es correcto. El valor de retorno se construye antes de que se destruyan las variables locales y, por lo tanto, antes de que se libere el bloqueo.