Un mutex es algo que agarras, y detendrá todos los otros hilos que intenten agarrarlo hasta que lo sueltes del hilo de agarre.
En su pregunta, tiene una función f asignando una instancia Mutex. Eso no es suficiente para bloquearlo. Tienes que llamar específicamente a mutex.lock() (en Qt, pero también en general, a menos que uses pthread, en ese caso usa pthread_mutex_lock y diviértete con cosas de bajo nivel que dependen de la plataforma. Qt lo resume muy bien).
He aquí un ejemplo con Qt
void MyClass::doStuff(int c)
{
mutex.lock();
a = c;
b = c * 2;
mutex.unlock();
}
Una vez que obtenga el bloqueo, la llamada ag() se hará desde el hilo que consiguió el bloqueo, por lo que será solo en esa llamada asumiendo que no está llamando g() desde otros subprocesos de otra parte del código. Bloquear no significa que detendrá todos los otros hilos. Detienerá los hilos que intenten obtener el mismo bloqueo, hasta que se suelte el bloqueo.
Si esa es la única forma en que tus hilos llegan a g(), entonces estás sincronizado en ese acceso.
Para la segunda parte de su pregunta, si el mutex es un atributo de instancia, entonces serán dos mutexes diferentes. Deberá declarar y crear instancias de una instancia mutex de clase y remitir a foro a su bloqueo. En ese caso, cualquier intento de invocar un método en la clase que bloquea el mutex de clase se sincronizará efectivamente, lo que significa que no habrá dos subprocesos que ejecutarán ese método juntos.
Por ejemplo (no tengo Qt, así que no puedo compilar este código, y dejé de codificación con él hace 2 años, por lo que no podía trabajar)
class Foo {
public:
void method(void) {
mutex.lock();
cout << "method called";
// long computation
mutex.unlock();
}
private:
QMutex mutex;
};
Ok, en este caso, supongamos que tiene dos hilos, 1 y 2, y dos instancias de la clase Foo, a y b. Supongamos que el hilo 1 llama a.method() y el hilo 2 llama a b.method(). En este caso, los dos mutexes son instancias diferentes, por lo que cada subproceso ejecutará la llamada, de forma independiente, y se ejecutará en paralelo.
Supongamos que tiene dos hilos, 1 y 2, y una instancia de la clase Foo que se comparte entre los dos hilos. si el hilo 1 llama a.method() y luego el hilo 2 llama a.method(), el hilo 2 se detendrá y esperará hasta que se libere el bloqueo del mutex.
Por último,
class Foo {
public:
void method(void) {
mutex.lock();
cout << "method called";
// long computation
mutex.unlock();
}
private:
static QMutex mutex;
};
QMutex Foo::mutex;
En este caso, el mutex es una variable estática clase. Solo tiene una instancia del mutex para cada instancia de objeto. Supongamos que tiene la misma situación que el primer caso anterior: dos hilos y dos instancias. En este caso, cuando el segundo subproceso intente llamar a b.method() tendrá que esperar a que a.method() se complete con el primer subproceso, ya que el bloqueo ahora es único y se comparte entre todas las instancias de su clase.
Para obtener más información, Qt tiene un buen tutorial sobre multithreading
https://doc.qt.io/qt-5/threads.html
+1 usando QT api –