Programación Concurrente 2do cuatrimestre 2016 Programación Concurrente Práctica 1: Modelo de cómputo y Exclusión Mutua 1. Dado el siguiente programa global x = 0 global y = 0 thread y = x + 1 thread x = y + 1 a) Mostrar una ejecución en el que los valores de las variables globales al final de la ejecución del programa son x = 2 e y = 1. b) Dar el diagrama de transición de estados. 2. Dado el siguiente programa global n = 0 thread l o c a l temp ; do 5 times temp = n n = temp + 1 thread l o c a l temp ; do 5 times temp = n n = temp + 1 Dar el diagrama de transición de estados. 3. Asumir que la función f tiene una raı́z entera, es decir, f (x) = 0 para algún valor x entero. A continuación proponemos distintos programas para encontrar tal raı́z. Consideraremos a un programa correcto si ambos threads terminan cuando uno de ellos ha encontrado la raı́z. Para cada programa, decir si es correcto o no, justificando la respuesta. Programa A global found thread local i = 0; found = f a l s e ; while ( not found ) i = i + 1; found = ( f ( i ) == 0 ) thread local j = 1; found = f a l s e ; while ( not found ) j = j − 1; found = ( f ( j ) == 0 ) Programa B global found = f a l s e thread local i = 0; while ( not found ) i = i + 1; found = ( f ( i ) == 0 ) thread local j = 1; while ( not found ) j = j − 1; found = ( f ( j ) == 0 ) Programa C global found = f a l s e thread local i = 0; while ( not found ) i = i + 1; i f ( f ( i ) == 0 ) found = true thread local j = 1; while ( not found ) j = j − 1; i f ( f ( j ) == 0 ) found = true 4. Considerar el siguiente programa global n = 0 thread while ( n < 2 ) print (n) thread n = n + 1; n = n + 1; 1 Programación Concurrente 2do cuatrimestre 2016 a) Debe necesariamente aparecer el valor 2 en la salida? b) Cuántas veces puede aparecer 2 en la salida? c) Cuántas veces puede aparecer 1 en la salida? d ) Cuántas veces puede aparecer 1 en la salida? e) Cual es la longitud de la secuencia mas corta que puede ser mostrada? 5. Considerar el siguiente programa global n = 0 thread while ( n < 1 ) n = n + 1 thread while ( n >= 0 ) n = n − 1 a) Existe una ejecución en la que el loop en el thread de la izquierda ejecute exactamente una vez? Justificar b) Existe una ejecución en la que el loop en el thread de la izquierda no termina?. 6. Considerar el siguiente programa global n = 0 global f l a g = f a l s e thread while ( not f l a g ) n = 1 − n thread while ( not f l a g ) if n = 0 f l a g = true a) Cuáles son los posibles valores de n cuando el programa termina. Justificar. b) Puede una ejecución del programa no terminar? 7. Considerar la siguiente versión del algoritmo de bakery para dos procesos. shared np = 0 ; nq= 0 ; thread p while ( true ) { np = nq+1 w h i l e ( nq != 0 && np > nq ){ } ; // s e c c i o n c r i t i c a np= 0 } thread q while ( true ) { nq = np+1 w h i l e ( np != 0 && nq > np ){ } ; // s e c c i o n c r i t i c a np= 0 } Resuelve este algoritmo el problema de la exclusión mutua? Justificar. 8. Considerar la siguiente propuesta para resolver el problema de la exclusión mutua. shared g1 = 0 ; g2= 0 ; thread i d=1 while ( true ) { l1 : repeat g1 = i d u n t i l g2 = 0 g2 = i d i f g1 <> i d i f g2 <> i d g o t o l 1 // s e c c i o n c r i t i c a g2 = 0 } thread i d=2 while ( true ) { l1 : repeat g1 = i d u n t i l g2 = 0 g2 = i d i f g1 <> i d i f g2 <> i d g o t o l 1 // s e c c i o n c r i t i c a g2 = 0 } Resuelve este algoritmo el problema de la exclusión mutua? Justificar. 9. Considerar la siguiente propuesta para resolver el problema de exclusión mutua para n procesos, que utiliza las siguientes funciones y variables compartidas: 2 Programación Concurrente 2do cuatrimestre 2016 actual = 0 turnos = 0 PedirTurno ( ) : turno = turnos turnos = turnos + 1 return turno LiberarTurno ( ) : actual = actual + 1 turnos = turnos − 1 Considere, también, que cada thread ejecuta el siguiente protocolo: // S e c c i o n no c r i t i c a t u r n o = PedirTurno ( ) while ( a c t u a l != t u r n o ) ; // S e c c i o n c r i t i c a LiberarTruno ( ) // S e c c i o n no c r i t i c a a) Mostrar que esta propuesta no resuelve el problema de la exclusión mutua. Indicar claramente cuál/es condición/es son violadas e ilustrar mostrando una traza. b) ¿Qué sucede si PedirTurno y LiberarTurno son operaciones atómicas? 10. Considerar la siguiente extensión del algoritmo de Peterson para n procesos (con n > 2) que utiliza las siguientes variables compartidas: f l a g : array [ 0 . . n−1] of boolean = { f a l s e } ; turno = 0 ; Además cada thread está identificado por el valor de la variable local threadId (que toma valores entre 0 y n − 1) . Cada thread utiliza el siguiente protocolo. ... // S e c c i o n no c r i t i c a f l a g [ t h r e a d I d ] = true ; t u r n o = ( t u r n o +1) mod n ; while ( f l a g [ o t r o ] && t u r n o == o t r o ) { } // S e c c i o n c r i t i c a f l a g [ Threadid ] = f a l s e ; // S e c c i o n no c r i t i c a ... Mostrar que esta variación no resuelve el problema de la exclusión mutua para n procesos, con n > 2. Indique claramente cuál/es condicion/es son violadas e ilustre mostrando una traza. 11. Considerar la siguiente propuesta para resolver el problema de la exclusión mutua para n procesos (con n > 2) que utiliza las siguientes variables compartidas: f l a g : array [ 0 . . n−1] of boolean = { f a l s e } ; y la siguiente función auxiliar algunVerdadero ( id ) : bool aux = f a l s e ; f o r i := 0 . . n−1 do i f i =!= i d then aux := aux | | r e t u r n aux ; flag [ i ] ; Además cada thread está identificado por el valor de la variable local threadId (que toma valores entre 0 y n − 1) . Cada thread utiliza el siguiente protocolo. . . . // S e c c i o n no c r i t i c a f l a g [ t h r e a d I d ] = true ; while ( ! a l g u n V e r d a d e r o ( t h r e a d I d ) ) { } 3 Programación Concurrente 2do cuatrimestre 2016 // S e c c i o n c r i t i c a f l a g [ Threadid ] = f a l s e ; // S e c c i o n no c r i t i c a . . . a) Mostrar que esta propuesta no resuelve el problema de la exclusión mutua para n procesos, con n > 2 si la operación algunVerdadero no es atómica. Indicar claramente cuál/es condicion/es son violadas e ilustrar mostrando una traza. b) Qué sucede si algunVerdadero es una operación atómica?. item Dado el algoritmo de bakery, mostrar que la condición j < id en el segundo while es necesaria. Es decir, muestre que el algoritmo que se obtiene al eliminar esta condición no resuelve el problema de la exclusión mutua. Mencionar al menos una propiedad que viola el algoritmo obtenido y mostrar una traza de ejecución que lo evidencie. Por comodidad, damos a continuación el algoritmo modificado (donde se eliminó la condición j < id ) shared e n t r a n d o [N] = { f a l s e , . . . , shared numero [N] = { 0 , . . . , 0} Thread ( i d ) // s e c c i o n no c r i t i c a e n t r a n d o [ i d ] = true numero [ i d ] = 1 + max( numero [ 1 ] , entrando [ id ] = f a l s e f o r ( j = 1 ; j <= n ; ++j ) while ( e n t r a n d o [ j ] ) ; while ( numero [ j ] != 0 false} ... , [n]) && ( numero [ j ] < numero [ i d ] | | ( numero [ j ] == numero [ i d ] ) ) ) ; // s e c c i o n c r i t i c a numero [ i d ] = 0 // s e c c i o n no c r i t i c a 12. Considere la operación atómica fetch-and-add definida de la siguiente manera: fetch−and−add( compartida , l o c a l , x ) l o c a l = compartida compartida = compartida + x y el siguiente algoritmo para resolver el problema de la exclusión mutua que utiliza las variables compartidas ticket y turno, ambas inicializadas en 0. i n t miturno // S e c c i o n no c r i t i c a fetch−and−add( t i c k e t , miturno , 1 ) while ( t u r n o != miturno ) { } // S e c c i o n C r i t i c a fetch−and−add( t i c k e t , miturno , −1) // S e c c i o n no C r i t i c a Indique si el algoritmo resuelve el problema de la exclusión mutua o no. Justifique (en caso negativo indicar que condición es violada y mostrar una traza). 13. Considere la siguiente operación tomarFlag ( mia , o t r o ) f l a g [ mia ] = ! f l a g [ o t r o ] Se propone el siguiente algoritmo para resolver el problema de la exclusión mutua entre dos procesos que utilizan el array compartido flag [0..1]= { false , false } 4 Programación Concurrente 2do cuatrimestre 2016 Thread 0 while ( ! f l a g [ 0 ] ) tomarFlag ( 0 , 1 ) c r i t i c a l section f l a g [0]= false Thread 1 while ( ! f l a g [ 1 ] ) tomarFlag ( 1 , 0 ) c r i t i c a l section f l a g [1]= false Se solicita: Asumiendo que la operación tomarFlag no es atómica, resuelve la propuesta anterior el problema de la exclusión mutua? Justifique su respuesta. En el caso en que tomarFlag es una acción atómica, el algoritmo es una solución al problema de la exclusión mutua. Justifique. 5