2011-09-26 25 views
7

私は複数のスレッドで作成できるクラスを持っています。しかし、ある関数ではコードを保護する必要があるので、私はboostプロセス間のmutexを使うことに決めました。すべてのクラスは、それのコンストラクタで同じミューテックスを作成するか、開きます。ブーストnamed_mutexとremove()コマンド

int MyClass::MyFunction() 
{ 
     boost::interprocess::scoped_lock<boost::interprocess::named_mutex> lock(
        m_Lock, boost::interprocess::try_to_lock); 
     if(!lock) 
     { 
      return -1; 
     } 
     // else do some stuff here 
} 

その関数の後にクリーンアップ(と好きに:

MyClass::MyClass() 
{ 
     boost::interprocess::named_mutex m_Lock(
       boost::interprocess::open_or_create, "myLock"); 
} 

だから今、重要なコード部分が呼び出されるポイントが来ます実際には、すべてこのコードは、正常に動作し

MyClass::~MyClass() 
{ 
     boost::interprocess::named_mutex::remove("myLock"); 
} 

が、私は持っている1つの懸念がある:

0私は私のクラスのデストラクタでremoveコマンドを使用します)ブーストページに記載

は、システムからの名前のミューテックスを消去します:それはremoveコマンドの説明で言われたよう

。エラー時にはfalseを返します。スローしないでください。

これは、システムからMutexを削除するだけで、別のスレッドがロックしたとしても(既にこのケースを試しましたが、もうロックされていない)、削除されます。 だから私の問題は、以下の通りである。たとえば 私は3つのスレッド(A、BおよびC)を持っている - 今、次の処理が行われます。Aは、クラスのインスタンスを作成する関数を呼び出し、それををロック

  1. プロセスを
  2. プロセスBは、クラスのインスタンスを作成する関数を呼び出すが、コードにアクセスすることができない(次に待ちなど)
  3. プロセスAは、保護されたコードで終了し、それが保護されたコードへ
  4. プロセスBゲインのアクセスをロック解除されますそれをロックする
  5. Proces ■クラスのインスタンスを削除します。 - > removeコマンドが呼び出されます。
  6. プロセスCは、クラスのインスタンスを作成し、関数を呼び出し、削除コマンドがMutex - >エラーを消去したためコードにアクセスできます。

だから、誰かが「次に削除しないでください!」と言うかもしれません。私はnamed_mutexがシステムに書き込むので、たとえプログラムが終了しても明示的な呼び出しがなければ消去されるのではないかと疑う。 誰かに助けがありますか?

+0

あなたの質問と「スレッド」と「プロセス」という用語の使い分けが混乱します。あなたはどちらを扱っていますか?スレッド?またはプロセス?あなたが単一のプロセス内でマルチスレッド化されているのであれば、名前付きの変異体は一般的に非常に限界的な有用性を持っています。 –

+0

それについて申し訳ありません - 私はちょうど書いている間、ちょっと混乱しています。実際に私は別のプロセスを持っています。あなたが言ったように、スレッドだけでは、名前付きmutexの実際の必要はありません。 – Toby

答えて

6

boost docsから、removeコールは不要です。 named_mutexのデストラクタは、プロセスにリソースが不要になったことをOSに自動的に通知します。おそらく、クリーンアップのためのデストラクタのビルトインの動作に頼っているだけで大​​丈夫でしょう。

明示的にremoveを呼び出すと、指定されたmutexを使用しようとしている他のプロセスやスレッドがmutexの操作で失敗する可能性があります。あなたの使い方がどのように編成されているかによって、これは他のプロセスでスローされるデータ競合やクラッシュ/例外を引き起こす可能性があります。

〜named_mutex();

Destroys *これは、リソースを使用して呼び出しプロセスが終了したことを示します。 デストラクタ関数は、この リソースに対して、このプロセスが使用するシステムによって割り当てられたすべてのシステム リソースを割り当て解除します。リソースはまだ開かれている コンストラクタのオーバーロードを呼び出すことができます。システムからリソースを消去するには、 remove()を使用します。

+0

もし私がremove()を呼んでいない限り、リソースはシステムに残っています(デストラクタが呼ばれても) - しかし、デストラクターがOSにリソースが "他のプロセスがロックする可能性がありますか?そうなの? – Toby

+0

私は自分自身であまりプレイしていませんが、ミューテックスを使用するプロセスの数がゼロになると、リソースが解放されると思います。 sem_close()はsemで参照されている名前付きセマフォを閉じ、システムが呼び出したプロセスに割り当てたすべてのリソースがこのセマフォを解放するために を解放できるようにします。 –

+10

ええ、私は昨日、やり直しと試行錯誤をしました。ミューテックスのリソースは共有メモリ(/ dev/shm /)にあります。作成後は、remove()を呼び出すか、システムを再起動するまでそこにとどまります。 (共有メモリを消去するなど、自分で消去するなど)オブジェクト自体には、ロックされているかどうかに関する情報が含まれています。ミューテックスが破壊されると、ロックが解除されますが、消去されません!だから唯一の問題は、プログラムが激しくクラッシュし、デストラクタを呼び出すことができず、オブジェクトがロックされたままであることです。 – Toby

0

おそらく、ミューテックスの共有使用カウンタが必要です。デストラクタ内のmutexをロックし、デクリメントし、デクリメント後にゼロの場合は、まだロックされているmutexの割り当てを解除します。あなたはそれによってあなたの現在の競争状態を防ぎます。