He sido aprovechado para el apoyo de código heredado, y estoy viendo algunas cosas que me causa a rascar mi cabeza en confusión. En algunas secciones de código, veo que una instancia de una clase utiliza un CMutex ejemplo, para sincronizar la ejecución del método. Por ejemplo

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

private:
   CMutex m_mutex;
}

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

   //...logic...

   m_mutex.Unlock();
}

Otros lugares en el mismo proyecto me parece que el código es el uso de un CSingleLock

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

private:
   CCriticalSection m_crit;
}

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

   //...logic...

   lock.Unlock();
}

Después de revisar Documentación de MSDN para la sincronización, parece que CClassB está implementando el mejor método, pero no es claro para mí lo que el peligro está en la implementación utilizada por CClassA. Por lo que puedo contar, la única diferencia entre los dos métodos es que CSingleLock tiene la ventaja de RAII, por lo que el bloqueo se libera automáticamente cuando la ejecución de las salidas de alcance. Hay otros beneficios /inconvenientes a la aplicación?

  • Para agregar un poco de contexto, una de mis preocupaciones es si el uso de CSingleLock::Lock ha sutilmente diferente comportamiento. Por ejemplo, cuando en el mismo hilo podría ser capaz de llamar a CMutex::Bloqueo varias veces (ya que ya posee el bloqueo), una llamada a CSingleLock::Bloqueo en la misma instancia de CSingleLock bloqueará. También me preocupa que me puede ejecutar en una situación en la que un CSingleLock es la gestión de un CCriticalSection, pero que CCriticalSection tiene el método de Desbloqueo llamado directamente.
InformationsquelleAutor JadeMason | 2011-05-19

2 Comentarios

  1. 2

    En general, los mutexes puede ser utilizado para controlar el hilo de acceso a través de procesos a través de un nombre de exclusión mutua, mientras que las secciones críticas son sólo para la sincronización de subprocesos de acceso en el mismo espacio de proceso.

    Ninguna de estas clases de realmente obtener el beneficio de RAII sin el embalaje de ellas, porque en ese caso nunca se tendría que llamar explícitamente a bloquear o desbloquear. Tomemos, por ejemplo, este poco de pseudo código mediante un impulso mutex lock …

    void DoSomething()
    {
      //construction acquires lock on mutex
      boost::scoped_lock lock(&aBoostMutex);
    
      //...
    
    } //end scope - object is destroyed and lock is released

    Ahora yo diría que usted debe evitar CMutex, CCritalSection, CSemaphore, y CEvent debido a que las implementaciones son algo roto o al menos muy inferior a la de otras bibliotecas como boost. Por ejemplo:

    • Determinar entre un tiempo de espera de un abandonado mutex es imposible, ya que la implementación de las comprobaciones de valor de retorno sólo no la razón.
    • No reentrante cierres con CSingleLock así recursividad va a causar problemas.
    • Incapacidad para tener un evento con nombre entre los procesos de

    Dependiendo de lo que se encargan de que usted podría tener la oportunidad de alejarse de las MFC contenedores en la API de windows y, o bien implementar su propio atómica bloqueos o usar algo como boost o C++0x características como std::mutex que no sólo son mejores implementaciones, pero proporcionan la cruz-plataforma de apoyo.

    • Por desgracia, estoy atascado con MFC. Mi pregunta era menos acerca de la diferencia entre CMutex y CCriticalSection, y más acerca de la diferencia entre CSyncObject::Lock y CSingleLock::Lock. Después de hacer un poco más de investigación, parece que CSingleLock se comporta de manera similar a la boost::scoped_lock se muestran arriba (llamadas de Desbloqueo en el destructor). No me di cuenta de CSingleLock impedido la recursividad, he asumido que cada nueva instancia en la pila se encargaría de gestionar de forma independiente.
    • CSyncObject llamadas de la api de Windows WaitForSingleObject debajo de las mantas hasta donde yo sé y no puede ser utilizado directamente. Es la clase base de la interfaz que CMutex deriva de por lo que se utiliza al hacer CMutex::Lock(); en su instancia. CSingleLock es su CCriticalSection manipulador que es concreto y puede ser utilizado como un ámbito de bloqueo con algunos de envolver. Como se mencionó antes, aunque hay algunos problemas de diseño con estos objetos, así que debe evitarse flounder.com/avoid_mfc_syncrhonization.htm
    • Para los lectores futuros, CSingleLock tiene un constructor parámetro que hará que se quede bloqueado en la construcción. La OP del ejemplo no se utiliza, qué tipo de derrotas que el principal motivo para utilizar un CSingleLock.
  2. 2

    Una sección crítica sólo es visible a/utilizable por los hilos dentro de un único proceso. Un mutex puede ser visible a través de una serie de procesos (normalmente mediante la creación de un nombre de exclusión mutua). Lo que he mostrado anteriormente no es suficiente para decir si esto es por qué tienen tanto, pero es una posibilidad.

    • Por lo que puedo decir, este código no tiene la necesidad de sincronización que cruza los límites del proceso. Esto me lleva a creer que la CMutex en CCLassA podría ser sustituido por un CCriticalSection.

Dejar respuesta

Please enter your comment!
Please enter your name here