GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cuál es la diferencia entre mutex y sección crítica?

Critical Section y Mutex no son específicos del sistema operativo, sus conceptos de subprocesos múltiples/multiprocesamiento.

Sección crítica Es un fragmento de código que solo debe ejecutarse por sí mismo en un momento dado (por ejemplo, hay 5 subprocesos que se ejecutan simultáneamente y una función llamada "función_de_sección_crítica" que actualiza una matriz... no desea que los 5 subprocesos actualicen el matriz a la vez. Entonces, cuando el programa ejecuta la función_sección_crítica(), ninguno de los otros subprocesos debe ejecutar su función_sección_crítica.

mutex* Mutex es una forma de implementar el código de la sección crítica (piense en ello como un token... el subproceso debe poseerlo para ejecutar el código_de_la_sección_crítica)


Para Windows, las secciones críticas son más livianas que los mutexes.

Las exclusiones mutuas se pueden compartir entre procesos, pero siempre dan como resultado una llamada del sistema al kernel que tiene cierta sobrecarga.

Las secciones críticas solo se pueden usar dentro de un proceso, pero tienen la ventaja de que solo cambian al modo kernel en caso de contención:las adquisiciones sin contención, que deberían ser el caso común, son increíblemente rápidas. En caso de contención, ingresan al kernel para esperar alguna primitiva de sincronización (como un evento o semáforo).

Escribí una aplicación de muestra rápida que compara el tiempo entre los dos. En mi sistema para 1,000,000 adquisiciones y liberaciones no disputadas, un mutex se hace cargo de un segundo. Una sección crítica tarda unos 50 ms en 1 000 000 de adquisiciones.

Aquí está el código de prueba, ejecuté esto y obtuve resultados similares si mutex es primero o segundo, por lo que no estamos viendo ningún otro efecto.

HANDLE mutex = CreateMutex(NULL, FALSE, NULL);
CRITICAL_SECTION critSec;
InitializeCriticalSection(&critSec);

LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
LARGE_INTEGER start, end;

// Force code into memory, so we don't see any effects of paging.
EnterCriticalSection(&critSec);
LeaveCriticalSection(&critSec);
QueryPerformanceCounter(&start);
for (int i = 0; i < 1000000; i++)
{
    EnterCriticalSection(&critSec);
    LeaveCriticalSection(&critSec);
}

QueryPerformanceCounter(&end);

int totalTimeCS = (int)((end.QuadPart - start.QuadPart) * 1000 / freq.QuadPart);

// Force code into memory, so we don't see any effects of paging.
WaitForSingleObject(mutex, INFINITE);
ReleaseMutex(mutex);

QueryPerformanceCounter(&start);
for (int i = 0; i < 1000000; i++)
{
    WaitForSingleObject(mutex, INFINITE);
    ReleaseMutex(mutex);
}

QueryPerformanceCounter(&end);

int totalTime = (int)((end.QuadPart - start.QuadPart) * 1000 / freq.QuadPart);

printf("Mutex: %d CritSec: %d\n", totalTime, totalTimeCS);

Además de las otras respuestas, los siguientes detalles son específicos de las secciones críticas de las ventanas:

  • en ausencia de contención, adquirir una sección crítica es tan simple como un InterlockedCompareExchange operación
  • la estructura de la sección crítica tiene espacio para un mutex. Inicialmente no está asignado
  • si hay conflicto entre subprocesos por una sección crítica, se asignará y utilizará la exclusión mutua. El rendimiento de la sección crítica se degradará al del mutex
  • si anticipa una alta contención, puede asignar la sección crítica especificando un conteo de giros.
  • si hay contención en una sección crítica con un conteo de vueltas, el subproceso que intenta adquirir la sección crítica girará (espera ocupada) durante esa cantidad de ciclos de procesador. Esto puede dar como resultado un mejor rendimiento que dormir, ya que la cantidad de ciclos para realizar un cambio de contexto a otro subproceso puede ser mucho mayor que la cantidad de ciclos que toma el subproceso propietario para liberar el mutex
  • si el conteo de giros caduca, se asignará el mutex
  • cuando el subproceso propietario libera la sección crítica, se requiere verificar si el mutex está asignado, si es así, configurará el mutex para liberar un subproceso en espera

En Linux, creo que tienen un "bloqueo de giro" que tiene un propósito similar al de la sección crítica con un conteo de giros.


Desde una perspectiva teórica, una sección crítica es una pieza de código que no debe ser ejecutada por varios subprocesos a la vez porque el código accede a recursos compartidos.

Un mutex es un algoritmo (y, a veces, el nombre de una estructura de datos) que se utiliza para proteger secciones críticas.

Los semáforos y los monitores son implementaciones comunes de un mutex.

En la práctica, hay muchas implementaciones mutex disponibles en Windows. Se diferencian principalmente como consecuencia de su implementación por su nivel de bloqueo, sus alcances, sus costos y su desempeño bajo diferentes niveles de contención. Consulte CLR Inside Out -Using concurrency for scalability para obtener un gráfico de los costos de diferentes implementaciones de mutex.

Primitivas de sincronización disponibles.

  • Supervisar
  • Mutex
  • Semáforo
  • Bloqueo Lector-Escritor
  • ReaderWriterLockSlim
  • Enclavado

El lock(object) La declaración se implementa usando un Monitor - vea MSDN para referencia.

En los últimos años se ha investigado mucho sobre la sincronización sin bloqueo. El objetivo es implementar algoritmos sin bloqueos ni esperas. En tales algoritmos, un proceso ayuda a otros procesos a terminar su trabajo para que el proceso finalmente pueda terminar su trabajo. En consecuencia, un proceso puede terminar su trabajo incluso cuando otros procesos, que intentaron realizar algún trabajo, se cuelgan. Al usar bloqueos, no liberarían sus bloqueos y evitarían que continuaran otros procesos.


Linux
  1. ¿Cuál es la diferencia entre Redhat y centOS?

  2. ¿Cuál es la diferencia entre strtok_r y strtok_s en C?

  3. ¿Cuál es la diferencia entre ls y l?

  4. ¿Cuál es la diferencia entre unlink y rm?

  5. ¿Cuál es la diferencia entre ruta y ruta ip?

¿Cuál es la diferencia entre Linux y Unix?

¿Cuál es la diferencia entre Shell de inicio de sesión y sin inicio de sesión?

¿Cuál es la diferencia entre el comando apt y apt-get?

¿Qué es un Hipervisor? ¿Cuál es la diferencia entre el tipo 1 y 2?

¿Cuál es la diferencia entre curl y Wget?

¿Cuál es la diferencia entre $(CC) y $CC?