6

I've been tapped to support some legacy code, and I'm seeing some things that cause me to scratch my head in confusion. In some sections of code, I see that a class instance uses a CMutex instance to synchronize method execution. For instance

class CClassA : public CObject
{
public:
   void DoSomething();

private:
   CMutex m_mutex;
}

void CClassA::DoSomething()
{
   m_mutex.Lock();

   //...logic...

   m_mutex.Unlock();
}

Elsewhere in the same project I find that the code is using a CSingleLock

class CClassB : public CObject
{
public:
   void DoSomething();

private:
   CCriticalSection m_crit;
}

void CClassB::DoSomething()
{
   CSingleLock lock(&m_crit);
   lock.Lock();

   //...logic...

   lock.Unlock();
}

After reviewing MSDN documentation for synchronization, it would appear that CClassB is implementing the advised method, but it isn't clear to me what the danger is in the implementation used by CClassA. As far as I can tell, the only difference between the two methods is that CSingleLock has the benefit of RAII, so the lock is automatically released when execution exits scope. Are there any other benefits / drawbacks to either implementation?

4

2 に答える 2

2

一般に、ミューテックスは、名前付きミューテックスを介してプロセス間のスレッドアクセスを制御するために使用できますが、クリティカルセクションは、同じプロセススペース内のスレッドアクセスを同期するためだけのものです。

これらのクラスはどちらも、ラップせずにRAIIのメリットを実際に得ることはできません。その場合、明示的にロックまたはロック解除を呼び出す必要がないためです。たとえば、ブーストミューテックスロックを使用したこの小さな擬似コードを見てください...

void DoSomething()
{
  // construction acquires lock on mutex
  boost::scoped_lock lock(&aBoostMutex);

  // ...

} // end scope - object is destroyed and lock is released

今、私はあなたが、、、を避けるべきだと主張しますCMutexCCritalSectionそしてCSemaphore実装CEventがいくらか壊れているか、少なくともブーストのような他の利用可能なライブラリより劣っているので。例えば:

  • 実装は理由だけでなく戻り値をチェックするため、放棄されたミューテックスからのタイムアウトを判別することは不可能です。
  • を使用したリエントラントロックCSingleLockはないため、再帰によって問題が発生します。
  • プロセス間で名前付きイベントを発生させることができない

任務に応じて、Windows APIのMFCラッパーから離れて、独自のアトミックロックを実装するか、ブーストやC ++ 0x機能などを使用する機会があります。これらの機能std::mutexは、より優れた実装であるだけでなく、クロスを提供します。 -プラットフォームのサポート。

于 2011-05-23T17:54:28.657 に答える
2

クリティカル セクションは、1 つのプロセス内のスレッドのみが表示/使用できます。ミューテックスは、(通常は名前付きミューテックスを作成することによって) 多数のプロセスにわたって可視にすることができます。あなたが上で示したことは、これが両方を持っている理由であるかどうかを言うのに十分ではありませんが、それは1つの可能性です.

于 2011-05-19T18:27:01.883 に答える