Hebras En Accion
Click here to load reader
-
Upload
stefano-salvatori -
Category
Technology
-
view
3.342 -
download
0
description
Transcript of Hebras En Accion
![Page 1: Hebras En Accion](https://reader038.fdocuments.es/reader038/viewer/2022100605/559b36c01a28ab49638b48ba/html5/thumbnails/1.jpg)
Hebras en acción
Cecilia Hernández
2007-1
![Page 2: Hebras En Accion](https://reader038.fdocuments.es/reader038/viewer/2022100605/559b36c01a28ab49638b48ba/html5/thumbnails/2.jpg)
Por qué usar hebras?
Explotar concurrencia Posible hacer varias tareas
concurrentemente• Varias hebras de ejecución en una
aplicación• Mientras tarea haciendo E/S otra usa CPU
Explotar parelismo Tareas ejecutándose en paralelo
![Page 3: Hebras En Accion](https://reader038.fdocuments.es/reader038/viewer/2022100605/559b36c01a28ab49638b48ba/html5/thumbnails/3.jpg)
Ejemplo simple con pthreads
// includes van aquí para pthread usar #include <pthread.h>#define NUM_HEBRAS 5void Hola(void *threadid){ printf("\n%d: Hola Hola!\n", threadid);}int main (int argc, char *argv[]){ pthread_t threads[NUM_HEBRAS]; int i, ret; for(i=0; i<NUM_HEBRAS; i++){ printf("creando hebra %d\n", i); ret = pthread_create(&threads[i], NULL,(void *)&Hola, (void *)i); if (ret){ printf("ERROR; pthread_create() retorna error %d\n", ret); exit(1); } } sleep(3); pthread_exit(NULL);}
![Page 4: Hebras En Accion](https://reader038.fdocuments.es/reader038/viewer/2022100605/559b36c01a28ab49638b48ba/html5/thumbnails/4.jpg)
Ejemplos
Sobreponiendo E/S Ejemplo simpleSecuencial.C Ejemplo simpleThread.C
Explotando paralelismo Ejemplo multiplicación de matrices
• www.inf.udec.cl/ejemplos/multMatrices.C• Nota implementación usa arreglos
unidimensionales para almacenar matrices• compilar como g++ -o xx xx.C -lpthread
![Page 5: Hebras En Accion](https://reader038.fdocuments.es/reader038/viewer/2022100605/559b36c01a28ab49638b48ba/html5/thumbnails/5.jpg)
Planificación de hebrasTambién válido para procesos
Planificador decide cuando ejecutar hebras/procesos listas
Aplicaciones no deberían asumir nada respecto al planificador Planificador es una caja negra
planificador
CPU
1 2 3 4 5
{4, 2, 3, 5, 1, 3, 4, 5, 2, …}
![Page 6: Hebras En Accion](https://reader038.fdocuments.es/reader038/viewer/2022100605/559b36c01a28ab49638b48ba/html5/thumbnails/6.jpg)
Qué problemas pueden surgir al usar hebras?
Aplicación hace algo incorrecto (Safety hazard) Ejemplo, problema de inconsistencia de datos Problema más común Condición de Carrera (Race
Condition)
Aplicación nunca hace lo correcto Bloqueo Mortal (Deadlocks)
Problema de desempeño Programa es muy lento porque usa demasiada
sincronización
![Page 7: Hebras En Accion](https://reader038.fdocuments.es/reader038/viewer/2022100605/559b36c01a28ab49638b48ba/html5/thumbnails/7.jpg)
Condición de Carrera
Salida de programa en ejecución varía y es dependiente de como las hebras involucradas fueron planificadas en la CPU Programadores deben velar por
correcto uso de recursos en sistema
![Page 8: Hebras En Accion](https://reader038.fdocuments.es/reader038/viewer/2022100605/559b36c01a28ab49638b48ba/html5/thumbnails/8.jpg)
Ejemplo 1
int suma = 0;void uno(int *p) { for (int i = 0; i < *p; i++) { suma++; }}int main(int argc, char *argv[]) { int r1, r2; if(argc != 3){ cout<<"Uso ./simple1 numero1 numero2"<<endl; exit(1); } r1 = atoi(argv[1]); r2 = atoi(argv[2]); uno(&r1); uno(&r2); cout<<"suma "<<suma<<endl;}
![Page 9: Hebras En Accion](https://reader038.fdocuments.es/reader038/viewer/2022100605/559b36c01a28ab49638b48ba/html5/thumbnails/9.jpg)
Caso secuencial Un proceso
Rutina uno es llamada dos veces secuencialmente en el tiempo
Suma siempre tendrá el mismo valor al terminar programa (dependiendo de valores de entrada)
Uno(100)
Uno(200)
tiempo
Suma=300
![Page 10: Hebras En Accion](https://reader038.fdocuments.es/reader038/viewer/2022100605/559b36c01a28ab49638b48ba/html5/thumbnails/10.jpg)
Ejemplo 2
//variable globalint suma = 0;
void *uno(void *p) { int *pi = (int *)p; for (int i = 0; i < *pi; i++) { suma++; }}
![Page 11: Hebras En Accion](https://reader038.fdocuments.es/reader038/viewer/2022100605/559b36c01a28ab49638b48ba/html5/thumbnails/11.jpg)
Ejemplo 2 (cont)
int main(int argc, char *argv[]){ int r1, r2; pthread_t thread1, thread2; if(argc != 3){ cout<<"Uso ./simple2 numero1 numero2"<<endl; exit(1); } r1 = atoi(argv[1]); r2 = atoi(argv[2]); if (pthread_create(&thread1, NULL, uno, (void *)&r1) != 0) perror("pthread_create"), exit(1); if (pthread_create(&thread2, NULL, uno, (void *)&r2) != 0) perror("pthread_create"), exit(1); if (pthread_join(thread1, NULL) != 0) perror("pthread_join"),exit(1); if (pthread_join(thread2, NULL) != 0) perror("pthread_join"),exit(1); cout<<"suma "<<suma<<endl;}
![Page 12: Hebras En Accion](https://reader038.fdocuments.es/reader038/viewer/2022100605/559b36c01a28ab49638b48ba/html5/thumbnails/12.jpg)
Caso multihebra
Un proceso Rutina uno asociada a dos hebras ejecutándose
concurrentemente Posibles salidas, alguna otra?
Uno(100)
Uno(200)
Uno(200)
Uno(100)
tiempo
Suma=300
Uno(100)
Uno(200)
Uno(200)
Uno(100)
Suma=283
Uno(100)
Uno(200)
Uno(200)
Uno(100)
Suma=290
Uno(200)
Uno(100)
![Page 13: Hebras En Accion](https://reader038.fdocuments.es/reader038/viewer/2022100605/559b36c01a28ab49638b48ba/html5/thumbnails/13.jpg)
Donde está el problema?
Sum es una variable global, compartida entre hebras en mismo proceso
Suma++ corresponde a más de una instrucción en lenguaje de máquina Leer de memoria, incrementar, escribir
en memoria Equivalente en MIPS
• lw $t0, offset($s0)• addi $t0, $t0, 1• sw $t0, offset($s0)
![Page 14: Hebras En Accion](https://reader038.fdocuments.es/reader038/viewer/2022100605/559b36c01a28ab49638b48ba/html5/thumbnails/14.jpg)
Vamos al detalle
Instrucciones se entrelazan en la ejecución concurrente de hebras Si suma = 0 inicialmente, cuál es el valor final?
Dado Hebra 1 y Hebra 2
tiempo lw $t0, offset($s0)
lw $t0, offset($s0)
addi $t0, $t0, 1
sw $t0, offset($s0)
addi $t0, $t0, 1
sw $t0, offset($s0)
Suma = ?
Planificador decide Cambio de hebra en CPU
![Page 15: Hebras En Accion](https://reader038.fdocuments.es/reader038/viewer/2022100605/559b36c01a28ab49638b48ba/html5/thumbnails/15.jpg)
Terminología
Código atómico: Sección de código que se ejecuta sin la intervención de otras hebras Ejecución toda o nada (como
transacción en bases de datos) Sección crítica: Sección de código
que accesa a recursos compartidos Recursos deben ser accesados
atómicamente