2011-08-31 15 views
12

Por ejemplo, ¿esto sería válido?¿Es válido anidar una sección crítica?

CRITICAL_SECTION cs; 

::InitializeCriticalSection(&cs); 

::EnterCriticalSection(&cs);  // First level 
::EnterCriticalSection(&cs);  // Second level 

/* do some stuff */ 

::LeaveCriticalSection(&cs);  // Second level 
::LeaveCriticalSection(&cs);  // First level 

::DeleteCriticalSection(&cs); 

Obviamente, yo nunca haría intencionalmente esto, pero lo que si esto llegara a suceder como resultado de las llamadas a funciones tales que el "primer nivel" es llamado a bloquear un objeto para un complejo (por ejemplo, búsqueda) Algoritmo y el "segundo nivel" se llama en las funciones de acceso de ese objeto?

Respuesta

23

Sí, es válido ingresar a la misma sección crítica mientras ya está dentro. De the docs:

Después de un hilo tiene la propiedad de una sección crítica, puede hacer llamadas adicionales a EnterCriticalSection o TryEnterCriticalSection sin bloquear su ejecución. Esto evita que un hilo se bloquee a sí mismo mientras espera una sección crítica que ya posee. El subproceso entra en la sección crítica cada vez que EnterCriticalSection y TryEnterCriticalSection tienen éxito. Un hilo debe llamar a LeaveCriticalSection una vez por cada vez que ingresó a la sección crítica .

+0

+1 ¡No sabía eso! – Valmond

+0

Lo mismo se aplica a todos los otros tipos de objetos de sincronización: mutex, semáforos, etc. Una vez que un hilo ha obtenido un bloqueo, puede volver a ingresar el bloqueo tantas veces como quiera sin bloquear. Solo asegúrese de liberar el bloqueo la misma cantidad de veces que lo ingrese para que se libere correctamente para que otros hilos obtengan. –

+1

@Remy: no, no se aplica a todos los demás tipos de objetos de sincronización. Ciertamente puede tener mutexes no reentrantes. –

9

Desde el documentation:

Después de un hilo tiene la propiedad de una sección crítica, puede hacer llamadas adicionales a EnterCriticalSection o TryEnterCriticalSection sin bloquear su ejecución. Esto evita que un hilo se bloquee a sí mismo mientras espera una sección crítica que ya posee. El subproceso entra en la sección crítica cada vez que EnterCriticalSection y TryEnterCriticalSection tienen éxito. Un hilo debe llamar a LeaveCriticalSection una vez por cada vez que ingrese a la sección crítica.

+0

Le gana 5 segundos: P –

+0

Sí, pero ... bueno, lo llamo un empate. – Cheeso

+0

+1 también para ti :-) – Valmond

0

Para validar las otras dos publicaciones. Una mirada rápida a la sección Crítica en WinDbg muestra que la sección cricital mantiene una variable entera para contener conteos de Recursividad.

0:001> dt RTL_CRITICAL_SECTION 
+0x000 DebugInfo : Ptr32 _RTL_CRITICAL_SECTION_DEBUG 
+0x004 LockCount : Int4B 
+0x008 RecursionCount : Int4B 
+0x00c OwningThread : Ptr32 Void 
+0x010 LockSemaphore : Ptr32 Void 
+0x014 SpinCount : Uint4B 

RecursionCount - Es posible que un hilo para adquirir una sección crítica más de una vez. Este campo indica cuántas veces el mismo hilo ha adquirido la sección crítica. Por defecto, , el valor de este campo es 0, lo que indica que no hay ningún subproceso que posea la sección crítica .

Cuestiones relacionadas