2012-07-25 11 views
5

Al intentar crear una clase de contenedor seguro para subprocesos desde cero, me he encontrado con el problema de devolver los valores de los métodos de acceso. Por ejemplo en Windows:Secciones críticas y valores devueltos en C++

myNode getSomeData() 
{ 
    EnterCriticalSection(& myCritSec); 
    myNode retobj; 
    // fill retobj with data from structure 
    LeaveCriticalSection(& myCritSec); 
    return retobj; 
} 

Ahora supongamos que este tipo de método no es en absoluto seguro para subprocesos, porque después del código libera la sección crítica otro hilo es capaz de venir y de inmediato sobrescribir retobj antes de que el primer hilo devoluciones. Entonces, ¿cuál es una forma elegante de devolver retobj a la persona que llama de una manera segura para hilos?

+1

Pero retobj se almacena en la pila? A menos que se declare como "estático", no debería tener problemas con la sobreescritura de los datos copiados. –

+0

A menos que ocurra algo extraño, 'retobj' debe estar en la pila, y cada hilo debe tener su propia pila. Las condiciones de carrera de este tipo son más comunes cuando trabajas con memoria asignada previamente y tienes que bloquear el acceso para evitar que se comparta. – ssube

+0

@inface, ok, buen punto, siempre que el valor de retorno se almacene en la pila, estoy bien. – ThomasMcLeod

Respuesta

7

No, es seguro para subprocesos porque cada subproceso tiene su propia pila, y ahí es donde está retobj.

Sin embargo, ciertamente no es una excepción. Ajustar la sección crítica en un objeto estilo RAII ayudaría a eso. Algo así como ...

class CriticalLock : boost::noncopyable { 
    CriticalSection &section; 

public: 
    CriticalLock(CriticalSection &cs) : section(cs) 
    { 
    EnterCriticalSection(section); 
    } 

    ~CriticalLock() 
    { 
    LeaveCriticalSection(section); 
    } 
}; 

Uso:

myNode getSomeData() 
{ 
    CriticalLock lock(myCritSec); // automatically released. 
    ... 
} 
2

Esto es C++, y retobj tiene un tipo de almacenamiento automático, por lo que se almacena en la pila.

Cada hilo tiene su propia pila, por lo que otro hilo no puede superar el valor de retobj antes de que se devuelva.

Cuestiones relacionadas