Lenguajes de Programación I
Ej. 4 – Parcial 2024
Se tiene un lenguaje con concurrencia bajo la forma de hilos de ejecución.
Aclaraciones: El diagrama 3 provoca una recursión infinita.
Se observan 3 pilas separadas
Existen 3 hilos
Uno es el main
El main crea 2 hilos a partir de la función f
func main() {
creahilo(f, 100)
creahilo(f, 200)
}
func f(id) {
}
Esto lo dice el enunciado
func main() {
creahilo(f, 100)
creahilo(f, 200)
}
func f(id) {
}
static z = 2
static_thread y = 2
x = 2
func main() {
creahilo(f, 100)
creahilo(f, 200)
}
func f(id) {
}
static z = 2
static_thread y = 2
x = 2
¿Qué se deduce del diagrama A?
f(id+1)
y - -
if y > 0
func main() {
creahilo(f, 100)
creahilo(f, 200)
}
func f(id) {
}
static z = 2
static_thread y = 2
x = 2
¿Qué se deduce del diagrama B?
f(id+1)
z - -
if z > 0
func main() {
creahilo(f, 100)
creahilo(f, 200)
}
func f(id) {
}
static z = 2
static_thread y = 2
x = 2
¿Qué se deduce del diagrama C?
f(id+1)
x - -
if x > 0
¿Por qué el programa tiene recursión infinita?
Disponible en: https://onecompiler.com/cpp/42x6k9whw
void f(int id){
int x=2;
static thread_local int y=2;
static int z = 2;
printf("id : %d, x: %d, y: %d, z: %d,\n",id,x,y,x);
printf("id : %d, &x: %d, &y: %d, &z: %d\n",id,&x,&y,&z);
VAR--;
if (VAR>0)
f(id+1);
}
int main (int argc, char *argv[]){
thread th1(f,100);
thread th2(f,200);
th1.join();
th2.join();
return 0;
}
Código en C++
func main() {
creahilo(f, 100)
creahilo(f, 200)
}
func f(id) {
}
static z = 2
static_thread y = 2
x = 2
f(id+1)
x - -
if x > 0
¿En cuál situación se comparte simultáneamente una variable?
func main() {
creahilo(f, 100)
creahilo(f, 200)
}
func f(id) {
}
static z = 2
static_thread y = 2
x = 2
f(id+1)
z - -
if z > 0
b) Indicar en cuál/es de las 3 situaciones es necesario un semáforo para evitar accesos simultáneos a variables.
En la situación B
Semaforo arriba
Semaforo abajo
c) Si se reemplaza la variable estática por otra que sea un puntero a una variable dinámica anónima y se modifica el programa para que sea esta variable la que se modifique, indicar si el programa correspondiente se comporta igual o no.
func main() {
creahilo(f, 100)
creahilo(f, 200)
}
func f(id) {
}
static z = new int
static_thread y = 2
x = 2
f(id+1)
*z - -
if *z > 0
El programa se comporta igual que en el caso que se decremente z, ya que de cualquier manera los hilos van a compartir el valor que se encuentra en el heap
func main() {
creahilo(f, 100)
creahilo(f, 200)
}
func f(id) {
}
static z = 2
static_thread y = 2
x = 2
f(id+1)
id - -
if id > 0
d) Realizar un diagrama de memoria en donde sea el parámetro id el que se decrementa. ¿Qué sucede con la ejecución?
z $10: 2
V.E.
main
id $220: 100;99
x $210: 2
y $200: 2
id $240: 100;99
x $230: 2
static
thread
f
f
id $520: 200;199
x $510: 2
y $500: 2
static
thread
f
id $260: 100;99
x $250: 2
f
id $540: 200;199
x $530: 2
f
…
…
Se produce una recursión infinita, ya que id se inicializa en cada llamado a f
e) Responder el inciso d) si el parámetro id se pasa por referencia, el parámetro real es la variable estática y el parámetro id es el que se decrementa.
func main() {
creahilo(f, 100)
creahilo(f, 200)
}
func f(id) {
}
static z = new int
static_thread y = 2
x = 2
f(ref z)
id - -
if id > 0
z $10: 2; 1; 0
V.E.
main
x $210: 2
y $200: 2
x $230: 2
static
thread
f
f
x $510: 2
y $500: 2
static
thread
f
x $250: 2
f
x $530: 2
f
…
…
Es la misma situación que cuando se modifica z
Errores frecuentes