Creo que puede tener un mutex declarado en la función llamada en sí o puede declararse como un miembro de clase o global. ¿Alguien puede explicar?
creando un nuevo mutex en la entrada no protege nada.
si estaba pensando en declarar un mutex estático (o global) para proteger a los miembros no estáticos, entonces también puede escribir el programa como un único programa de subprocesos (vale, hay algunos casos de esquina). un bloqueo estático bloquearía todos los hilos excepto uno (asumiendo el concurso); es equivalente a "un máximo de un hilo puede operar en el cuerpo de este método a la vez". declarar un mutex estático para proteger los datos estáticos está bien. como David Rodríguez - Dribeas lo formuló sucintamente en los comentarios de otra respuesta: "El mutex debería estar al nivel de los datos que se están protegiendo".
que puede declara una variable miembro, por ejemplo, que tomaría la forma generalizada:
class t_object {
public:
...
bool getData(t_data& outData) {
t_lock_scope lock(this->d_lock);
...
outData.set(someValue);
return true;
}
private:
t_lock d_lock;
};
que el enfoque está muy bien, y en algunos casos ideales. tiene sentido en la mayoría de los casos cuando construyes un sistema donde las instancias intentan abstraer la mecánica de bloqueo y los errores de sus clientes. Una desventaja es que puede requerir más adquisiciones y típicamente requiere mecanismos de bloqueo más complejos (por ejemplo, reentrada). por más adquisiciones: el cliente puede saber que una instancia se utiliza en un solo hilo: ¿por qué bloquear en ese caso? Además, un montón de pequeños métodos de fabricación de hilos introducirán una gran cantidad de sobrecarga. con el bloqueo, quiere entrar y salir de las zonas protegidas lo antes posible (sin introducir muchas adquisiciones), por lo que las secciones críticas son a menudo operaciones más grandes que las típicas.
si la interfaz pública requiere este bloqueo como un argumento (como se ve en el ejemplo), es una señal de que su diseño se puede simplificar mediante la privatización de bloqueo (haciendo la función de objeto de una manera segura hilo, en lugar de pasar el bloqueo como un recurso externo).
utilizando un bloqueo externo (o vinculado o asociado), puede reducir las adquisiciones (o el tiempo total bloqueado). este enfoque también le permite agregar bloqueo a una instancia después del hecho. también le permite al cliente configurar cómo funciona el bloqueo. el cliente puede usar menos bloqueos al compartirlos (en un conjunto de instancias). incluso un simple ejemplo de composición puede ilustrar este (con soporte para ambos modelos):
class t_composition {
public:
...
private:
t_lock d_lock; // << name and data can share this lock
t_string d_name;
t_data d_data;
};
teniendo en cuenta la complejidad de algunos sistemas multiproceso, empujando la responsabilidad de bloqueo apropiada sobre el cliente puede ser una muy mala idea .
ambos modelos (vinculados y como variable de miembro) se pueden utilizar con eficacia. lo que es mejor en un escenario dado varía según el problema.
Debe agregar un ejemplo particular donde se usa. Probablemente se deba a la semántica que se implementa en el ejemplo, y no se puede responder sin contexto (a menos que desee genérico * solo porque * o * pueda tener sentido * respuestas) –