No es posible que dos (o más) subprocesos adquieran bloqueo al mismo tiempo. Hay pocos tipos de métodos de sincronización, por ejemplo:
Espera activa - bloqueo de giro
Pseudocódigo:
1. while ( xchg(lock, 1) == 1); - entry protocole
XCHG es un ejemplo de operación atómica (existe en la arquitectura x86) que primero establece un nuevo valor para una variable de "bloqueo" y luego devuelve un valor antiguo. Atómico significa que no se puede interrumpir, en el ejemplo anterior entre establecer un nuevo valor y devolver el antiguo. Atómico - resultado determinista pase lo que pase.
2. Your code
3. lock = 0; - exit protocol
Cuando el bloqueo es igual a 0, otro hilo puede ingresar a la sección crítica, mientras el bucle termina.
Hilo suspendido - por ejemplo contando semáforo
Existen dos operación atómica .Wait()
y .Signal()
y tenemos la variable entera le llaman int currentValue
.
Wait():
if (currentValue > 0) currentValue -= 1;
else suspend current thread;
Signal():
If there exists thread suspended by semaphore wake up one of them
Else currentValue += 1;
Ahora resolver el problema de la sección crítica es realmente fácil:
Pseudocódigo:
mySemaphore.Wait();
do some operations - critical section
mySemaphore.Signal();
Por lo general, su API de subproceso de programación debería permitirle especificar subprocesos simultáneos máximos en la sección crítica del semáforo. Obviamente, hay más tipos de sincronización en sistemas multiproceso (mutex, monitores, semáforos binarios, etc.) pero se basan en las ideas anteriores. Se podría argumentar que los métodos que utilizan la suspensión de subprocesos deberían preferirse a la espera activa (por lo que no se desperdicia la CPU), no siempre es la verdad. Cuando se suspende el subproceso, se realiza una operación costosa llamada cambio de contexto. Sin embargo, es razonable cuando el tiempo de espera es corto (número de hilos ~ número de núcleos).