• Like
Hebras En Accion
Upcoming SlideShare
Loading in...5
×
Uploaded on

Hebras

Hebras

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
3,285
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
103
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Hebras en acción Cecilia Hernández 2007-1
  • 2. 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
  • 3. Ejemplo simple con pthreads // includes van aquí para pthread usar #include <pthread.h> #define NUM_HEBRAS 5 void Hola(void *threadid) { printf(&quot; %d: Hola Hola! &quot;, threadid); } int main (int argc, char *argv[]) { pthread_t threads[NUM_HEBRAS]; int i, ret; for(i=0; i<NUM_HEBRAS; i++){ printf(&quot;creando hebra %d &quot;, i); ret = pthread_create(&threads[i], NULL,(void *)&Hola, (void *)i); if (ret){ printf(&quot;ERROR; pthread_create() retorna error %d &quot;, ret); exit(1); } } sleep(3); pthread_exit(NULL); }
  • 4. 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
  • 5. Planificación de hebras Tambié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, …}
  • 6. 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
  • 7. 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
  • 8. 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<<&quot;Uso ./simple1 numero1 numero2&quot;<<endl;
    • exit(1);
    • }
    • r1 = atoi(argv[1]);
    • r2 = atoi(argv[2]);
    • uno(&r1);
    • uno(&r2);
    • cout<<&quot;suma &quot;<<suma<<endl;
    • }
  • 9. 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
  • 10. Ejemplo 2
    • //variable global
    • int suma = 0;
    • void *uno(void *p) {
    • int *pi = (int *)p;
    • for (int i = 0; i < *pi; i++) {
    • suma++;
    • }
    • }
  • 11. Ejemplo 2 (cont)
    • int main(int argc, char *argv[])
    • {
    • int r1, r2;
    • pthread_t thread1, thread2;
    • if(argc != 3){
    • cout<<&quot;Uso ./simple2 numero1 numero2&quot;<<endl;
    • exit(1);
    • }
    • r1 = atoi(argv[1]);
    • r2 = atoi(argv[2]);
    • if ( pthread_create(&thread1, NULL, uno, (void *)&r1) != 0)
    • perror(&quot;pthread_create&quot;), exit(1);
    • if ( pthread_create(&thread2, NULL, uno, (void *)&r2) != 0)
    • perror(&quot;pthread_create&quot;), exit(1);
    • if (pthread_join(thread1, NULL) != 0)
    • perror(&quot;pthread_join&quot;),exit(1);
    • if (pthread_join(thread2, NULL) != 0)
    • perror(&quot;pthread_join&quot;),exit(1);
    • cout<<&quot;suma &quot;<<suma<<endl;
    • }
  • 12. 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)
  • 13. 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)
  • 14. 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
  • 15. 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