Sincronización entre Procesos II Leopoldo Taravilse1 1 Departamento de Computación Sistemas Operativos 11/09/2014 Leopoldo Taravilse (DC-UBA) Semáforos 11/09/2014 1 / 80 Semáforos Mutex Mutual Exclusion (Mutex o Exclusión Mutua) Lograr el acceso exclusivo a una variable o porción de código. Leopoldo Taravilse (DC-UBA) Semáforos 11/09/2014 2 / 80 Semáforos Mutex Mutual Exclusion (Mutex o Exclusión Mutua) 1 int critica = 0; 2 3 4 5 A(): critica++; printf("%d\n",critica); 6 7 8 9 B(): critica--; printf("%d\n",critica); Leopoldo Taravilse (DC-UBA) Semáforos 11/09/2014 3 / 80 Semáforos Mutex Mutual Exclusion (Mutex o Exclusión Mutua) 1 2 int critica = 0; sem mutex = Semaphore(1); 3 4 5 6 7 8 A(): mutex.wait(); critica++; printf("%d\n",critica); mutex.signal(); 9 10 11 12 13 14 B(): mutex.wait(); critica--; printf("%d\n",critica); mutex.signal(); Leopoldo Taravilse (DC-UBA) Semáforos 11/09/2014 4 / 80 Semáforos Rendezvouz Rendezvous (Encuentro) Leopoldo Taravilse (DC-UBA) Semáforos 11/09/2014 5 / 80 Semáforos Rendezvouz Rendezvous (Encuentro) Dados dos procesos A y B, logra que ambos se encuentren en determinado punto del código antes de seguir ejecutando. Leopoldo Taravilse (DC-UBA) Semáforos 11/09/2014 5 / 80 Semáforos Rendezvouz Rendezvous (Encuentro) 1 int critica = 0; 2 3 4 5 A(): critica++; printf("%d\n",critica); 6 7 8 9 B(): critica--; printf("%d\n",critica); Cómo hacemos para que los dos procesos impriman 0? Leopoldo Taravilse (DC-UBA) Semáforos 11/09/2014 6 / 80 Semáforos Rendezvouz Rendezvous (Encuentro) 1 int critica = 0; 2 3 4 5 A(): critica++; printf("%d\n",critica); 6 7 8 9 B(): critica--; printf("%d\n",critica); Cómo hacemos para que los dos procesos impriman 0? Pensemos el código como algo más general, tenemos dos segmentos de código en cada proceso, y queremos que el primer segmento de cada proceso se ejecute antes que el segundo segmento de código de cada proceso. Leopoldo Taravilse (DC-UBA) Semáforos 11/09/2014 6 / 80 Semáforos Rendezvouz Rendezvous (Encuentro) 1 2 3 A(): f1(); f2(); 4 5 6 7 B(): g1(); g2(); Leopoldo Taravilse (DC-UBA) Semáforos 11/09/2014 7 / 80 Semáforos Rendezvouz Rendezvous (Encuentro) 1 2 3 A(): f1(); f2(); 4 5 6 7 B(): g1(); g2(); Hint: tenemos dos semáforos a y b inicializados en cero que nos dicen cuándo ya se ejecutó f1 y f2 Leopoldo Taravilse (DC-UBA) Semáforos 11/09/2014 7 / 80 Semáforos Rendezvouz Rendezvous (Encuentro) 1 2 3 4 5 A(): f1(); a.signal(); b.wait(); f2(); 6 7 8 9 10 11 B(): g1(); b.signal(); a.wait(); g2(); Leopoldo Taravilse (DC-UBA) Semáforos 11/09/2014 8 / 80 Semáforos Barrera Barrera Es la idea de Rendezvous extendida a N procesos. Leopoldo Taravilse (DC-UBA) Semáforos 11/09/2014 9 / 80 Semáforos Barrera Barrera 1 2 3 A(i): f(i); g(i); Leopoldo Taravilse (DC-UBA) Semáforos 11/09/2014 10 / 80 Semáforos Barrera Barrera 1 2 3 A(i): f(i); g(i); Cómo hacemos para que cada proceso ejecute su g(i) una vez que todos los procesos ejecutaron su f(i)? Leopoldo Taravilse (DC-UBA) Semáforos 11/09/2014 10 / 80 Semáforos Barrera Barrera 1 2 3 4 5 6 7 8 9 10 11 12 13 14 int n = N; sem mutex = Semaphore(1); sem b = Semaphore(0); A(i): f(i); mutex.wait(); //Acceso exclusivo n--; yo = n; mutex.signal(); if (yo == 0) // Soy el ultimo b.signal(); b.wait(); b.signal(); // <- wait+signal = turnstile g(i); Leopoldo Taravilse (DC-UBA) Semáforos 11/09/2014 11 / 80 Semáforos Barrera Barrera 1 2 3 4 5 6 7 8 9 10 11 12 13 int n = N; sem mutex = Semaphore(1); sem b = Semaphore(0); A(i): f(i); mutex.wait(); //Acceso exclusivo n--; yo = n; mutex.signal(); if (yo == 0) // Soy el ultimo b.signal(N); b.wait(); g(i); Leopoldo Taravilse (DC-UBA) Semáforos 11/09/2014 12 / 80 Semáforos Cola ordenada Cola ordenada Los procesos deben acceder a la sección critica en orden FIFO. Leopoldo Taravilse (DC-UBA) Semáforos 11/09/2014 13 / 80 Semáforos Cola ordenada Cola ordenada 1 2 1 2 3 4 P(i): f(i); //<-- Seccion critica Q(): while(true) g(); // <-- Aca corren los P en orden. Leopoldo Taravilse (DC-UBA) Semáforos 11/09/2014 14 / 80 Semáforos Cola ordenada Cola ordenada 1 2 1 2 3 4 P(i): f(i); //<-- Seccion critica Q(): while(true) g(); // <-- Aca corren los P en orden. cómo hacemos para que los procesos P ejecuten f(i) en el orden en que llegaron, luego de que Q ejecute g()? Leopoldo Taravilse (DC-UBA) Semáforos 11/09/2014 14 / 80 Semáforos Cola ordenada Cola ordenada 1 2 1 2 3 cola c = CrearColaVacia(); sem mutex = Semaphore(1); sem colaNoVacia = Semaphore(0); 3 4 5 4 5 6 7 8 9 10 11 6 Q(): while(true) g(); colaNoVacia.wait(); m.wait(); c.top().signal(); m.signal(); 7 8 9 10 11 12 13 14 15 Leopoldo Taravilse (DC-UBA) Semáforos P(i): sem yo = Semaphore(0); m.wait(); n = c.size(); c.push(yo); m.signal(); if (n == 0) colaNoVacia.signal(); yo.wait(); f(); m.wait(); c.pop(); if (!c.empty()) c.top().signal(); m.signal(); 11/09/2014 15 / 80 Semáforos Cola ordenada Cola ordenada 1 2 1 2 3 cola c = CrearColaVacia(); sem mutex = Semaphore(1); sem colaNoVacia = Semaphore(0); 3 4 5 4 5 6 7 8 9 10 11 6 Q(): while(true) g(); colaNoVacia.wait(); m.wait(); c.top().signal(); m.signal(); 7 8 9 10 11 12 13 14 15 Leopoldo Taravilse (DC-UBA) Semáforos P(i): sem yo = Semaphore(0); m.wait(); n = c.size(); c.push(yo); m.signal(); if (n == 0) colaNoVacia.signal(); yo.wait(); f(); m.wait(); c.pop(); if (!c.empty()) c.top().signal(); m.signal(); 11/09/2014 15 / 80 Semáforos Cola ordenada Otras estructuras La misma idea se puede usar para simular cualquier estructura que tenga un orden definido de cómo sacar elementos. Por ejemplo, una pila, o una cola de prioridad que puede estar implementada con un heap. Leopoldo Taravilse (DC-UBA) Semáforos 11/09/2014 16 / 80