実装定義だと思います。
ミューテックスが十分であるかどうかは、ミューテックスをクリティカルセクションのメカニズムと見なすか、それ以上のものと見なすかによって異なります。
http://en.cppreference.com/w/cpp/thread/mutex/unlockで述べられているように、
ミューテックスは現在の実行スレッドによってロックされている必要があります。そうでない場合、動作は定義されていません。
つまり、スレッドは、C++でそれ自体がロック/所有しているミューテックスのみをロック解除できました。
ただし、他のプログラミング言語では、プロセス間でミューテックスを共有できる場合があります。
したがって、2つの概念を区別することは単にパフォーマンスの考慮事項である可能性があり、複雑な所有権の識別またはプロセス間共有は単純なアプリケーションには価値がありません。
たとえば、追加のミューテックスを使用して@slowjeljのケースを修正できます(これは誤った修正である可能性があります)。
スレッド1:
lock(mutex0);
while(1) {
lock(mutex0); // Blocks waiting for notification from Thread2
... // do work after notification is received
unlock(mutex1); // Tells Thread2 we are done
}
スレッド2:
while(1) {
lock(mutex1); // lock the mutex so Thread1 will block again
... // do the work that precedes notification
unlock(mutex0); // unblocks Thread1
}
ただし、プログラムは、コンパイラによって残されたアサーションをトリガーしたことを通知します(たとえば、Visual Studio 2015の「所有されていないミューテックスのロック解除」)。