ミューテックスはあなたがつかむものであり、グラブしているスレッドから解放するまで、それをつかもうとする他のスレッドを停止します。
あなたの質問には、Mutex インスタンスを割り当てる関数があります。それはそれをロックするのに十分ではありません。具体的には、mutex.lock() を呼び出す必要があります (Qt でも一般的に、pthread を使用しない限り、その場合は pthread_mutex_lock を使用して、プラットフォームに依存する低レベルのものを楽しんでください。Qt はそれを非常にうまく抽象化します)。
ここにQtの例があります
void MyClass::doStuff( int c )
{
mutex.lock();
a = c;
b = c * 2;
mutex.unlock();
}
ロックを取得すると、ロックを取得したスレッドから g() の呼び出しが行われるため、コードの別の部分から他のスレッドから g() を呼び出していないと仮定すると、その呼び出しでは単独になります。ロックは、他のすべてのスレッドを停止するという意味ではありません。ロックが解放されるまで、同じロックを取得しようとするスレッドを停止します。
それがスレッドが g() に到達する唯一の方法である場合、そのアクセスで同期されます。
質問の 2 番目の部分では、ミューテックスがインスタンス属性の場合、それらは 2 つの異なるミューテックスになります。クラスミューテックスインスタンスを宣言してインスタンス化し、ロックのために参照する必要があります。その場合、クラスミューテックスをロックするクラス内のメソッドを呼び出そうとすると、効果的に同期されます。つまり、2 つのスレッドがそのメソッドを一緒に実行することはありません。
たとえば、(私は Qt を持っていないので、このコードをコンパイルできず、2 年前にコーディングを停止したため、動作しませんでした)
class Foo {
public:
void method(void) {
mutex.lock();
cout << "method called";
// long computation
mutex.unlock();
}
private:
QMutex mutex;
};
この場合、1 と 2 の 2 つのスレッドと、クラス Foo の 2 つのインスタンス a と b があるとします。スレッド 1 が a.method() を呼び出し、スレッド 2 が b.method() を呼び出すとします。この場合、2 つのミューテックスは異なるインスタンスであるため、各スレッドは独立して呼び出しを実行し、並行して実行されます。
1 と 2 の 2 つのスレッドと、2 つのスレッド間で共有されるクラス Foo の 1 つのインスタンスがあるとします。スレッド 1 が a.method() を呼び出し、次にスレッド 2 が a.method() を呼び出した場合、スレッド 2 は停止し、mutex ロックが解放されるまで待機します。
ついに、
class Foo {
public:
void method(void) {
mutex.lock();
cout << "method called";
// long computation
mutex.unlock();
}
private:
static QMutex mutex;
};
QMutex Foo::mutex;
この場合、mutex はクラスの静的変数です。オブジェクト インスタンスごとにミューテックスのインスタンスが 1 つだけあります。上記の最初のケースと同じ状況 (2 つのスレッドと 2 つのインスタンス) があるとします。この場合、2 番目のスレッドが b.method() を呼び出そうとすると、最初のスレッドによって a.method() が完了するまで待機する必要があります。これは、ロックが一意になり、クラスのすべてのインスタンス間で共有されるためです。
詳細については、Qt にマルチスレッドに関する優れたチュートリアルがあります。
https://doc.qt.io/qt-5/threads.html