web-dev-qa-db-ja.com

「ミューテックス」と「ロック」の違いは何ですか?

ロックとミューテックスの違いについて私は非常に混乱しています。 Boostのドキュメントでは、次のように述べています。

ロックタイプ

  • クラステンプレートlock_guard
  • クラステンプレートunique_lock
  • クラステンプレートshared_lock
  • クラステンプレートupgrade_lock
  • クラステンプレートupgrade_to_unique_lock
  • ミューテックス固有のクラスscoped_try_lock

ミューテックスタイプ

  • クラスミューテックス
  • Typedef try_mutex
  • クラスtimed_mutex
  • クラスrecursive_mutex
  • Typedef recursive_try_mutex
  • クラスrecursive_timed_mutex
  • クラスshared_mutex

別の記事では、私はこのような関数を見ます、

boost::shared_mutex _access;
void reader()
{
  boost::shared_lock< boost::shared_mutex > lock(_access);
  // do work here, without anyone having exclusive access
}    
void conditional_writer()
{
  boost::upgrade_lock< boost::shared_mutex > lock(_access);
  // do work here, without anyone having exclusive access

  if (something) {
    boost::upgrade_to_unique_lock< boost::shared_mutex > uniqueLock(lock);
    // do work here, but now you have exclusive access
  }
  // do more work here, without anyone having exclusive access
}

更新された質問

  1. 誰かが「ミューテックス」と「ロック」の間の説明を提供できますか?
  2. shared_mutexに対してshared_lockを作成する必要がありますか? shared_mutexに対してnique_lockを作成するとどうなりますか?
  3. または、mutexに対してshared_lockを作成した場合、ミューテックスを複数のスレッド間で共有できないことを意味しますか?
23
2607

mutexは同期オブジェクトです。他のスレッドが同じデータに同時にアクセスしないようにするために、コードのセクションの最初でミューテックスのロックを取得し、最後にそれを解放します。ミューテックスは通常、保護しているデータのライフタイムと同じライフタイムを持ち、1つのミューテックスは複数のスレッドによってアクセスされます。

ロックオブジェクトは、そのロックをカプセル化するオブジェクトです。オブジェクトが構築されると、ミューテックスのロックを取得します。破壊されると、ロックが解除されます。通常、共有データへのアクセスごとに新しいロックオブジェクトを作成します。

40

ミューテックスは、ロックできるオブジェクトです。ロックは、ロックを維持するオブジェクトです。ロックを作成するには、ロックをミューテックスに渡す必要があります。

14
James Kanze

ロックは相互排除を提供できますが、条件の同期は提供できません。セマフォとは異なり、ロックには所有者があり、所有権はロックの動作において重要な役割を果たします。

例-

class lockableObject { public void F() {
mutex.lock(); ...; mutex.unlock();
}
public void G() {
mutex.lock(); ...; F(); ...; mutex.unlock();
}
private mutexLock mutex; }
// method G() calls method F()

クラスlockableObjectのロックミューテックスは、メソッドF()およびG()をクリティカルセクションに変換するために使用されます。したがって、一度に1つのスレッドのみが内部で実行できます。 lockableObjectのメソッド。スレッドがメソッドG()を呼び出すと、ミューテックスがロックされます。メソッドG()がメソッドF()を呼び出すと、mutex.lock()がF()で実行されます。 )が、呼び出し元のスレッドはすでにミューテックスを所有しているためブロックされません。ミューテックスがロックではなくバイナリセマフォである場合、G()からF()は、F()でmutex.P()が実行されたときに、呼び出し元のスレッドをブロックします(P()およびV()操作は交互​​に行う必要があります。)F()またはG()内で他のスレッドを実行できないため、デッドロックが発生します。

ロックとバイナリセマフォの違いは次のとおりです。1バイナリセマフォの場合、V()への呼び出しを介さずに2つの呼び出しがP()に対して行われると、2番目の呼び出しがブロックされます。ただし、ロックを所有し、所有権を再度要求するスレッドはブロックされません。 (ロックは常に再帰的であるとは限らないことに注意してください。ロックを使用する前にドキュメントを確認してください。)2 lock()とunlock()を連続して呼び出す所有者は同じスレッドである必要があります。ただし、P()とV()の連続呼び出しは、異なるスレッドによって行うことができます。

1
sujeet