Ver Mensaje Individual
  #2 (permalink)  
Antiguo 08/03/2015, 17:37
Avatar de razpeitia
razpeitia
Moderador
 
Fecha de Ingreso: marzo-2005
Ubicación: Monterrey, México
Mensajes: 7.321
Antigüedad: 19 años, 2 meses
Puntos: 1360
Respuesta: Uso de Threads en C

Bueno tienes problemas de concurrencia, porque usas un contador en lugar de enviar un parámetro con el indice que usara.

Supón que inicias todos los threads y se empieza a ejecutar al mismo tiempo. Obviamente cont va a tener 0 en varias de esas llamadas de hecho lo puedes visualizar mejor si imprimes cont.

Código C:
Ver original
  1. printf("Número aleatorio: (%d) %d \n", cont, aleatorios[cont]);

Para evitar eso, creas un arreglo de parametros y lo llenas con los parametros que ocupas.
Código C:
Ver original
  1. struct hilos_random_parms
  2. {
  3.     int randi;
  4.     int index;
  5. };
  6.  
  7. struct hilos_random_parms thread1_args[5];
  8. int i;
  9. for(i = 0; i < 5; i++) {
  10.     thread1_args[i].randi = 10;
  11.     thread1_args[i].index = i;
  12. }

Haces lo mismo al pasarlos
Código C:
Ver original
  1. pthread_create(&thread1_id, NULL, &hilos_random, &thread1_args[0]);
  2.     pthread_create(&thread2_id, NULL, &hilos_random, &thread1_args[1]);
  3.     pthread_create(&thread3_id, NULL, &hilos_random, &thread1_args[2]);
  4.     pthread_create(&thread4_id, NULL, &hilos_random, &thread1_args[3]);
  5.     pthread_create(&thread5_id, NULL, &hilos_random, &thread1_args[4]);

Por ultimo sustituyes cont
Código C:
Ver original
  1. int cont = p->index;
  2.  
  3. // Lo añades al SEED porque si no obtendras siempre los mismos numeros.
  4. srand(time(NULL) + cont);


Al final te quedara algo así:
Código C:
Ver original
  1. #include <pthread.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4.  
  5. struct hilos_random_parms
  6. {
  7.     int randi;
  8.     int index;
  9. };
  10.  
  11. int aleatorios[5];
  12.  
  13. void* hilos_random(void* parameters)
  14. {
  15.     struct hilos_random_parms* p = (struct hilos_random_parms*)parameters;
  16.     int cont = p->index;
  17.     srand(time(NULL) + cont);
  18.     aleatorios[cont] = (rand() % p->randi) + 1;
  19.     printf("Número aleatorio: (%d) %d \n", cont, aleatorios[cont]);
  20.     cont++;
  21.     return NULL;
  22. }
  23.  
  24. int main()
  25. {
  26.     pthread_t thread1_id;
  27.     pthread_t thread2_id;
  28.     pthread_t thread3_id;
  29.     pthread_t thread4_id;
  30.     pthread_t thread5_id;
  31.  
  32.     struct hilos_random_parms thread1_args[5];
  33.     int i;
  34.     for(i = 0; i < 5; i++) {
  35.         thread1_args[i].randi = 10;
  36.         thread1_args[i].index = i;
  37.     }
  38.  
  39.  
  40.     pthread_create(&thread1_id, NULL, &hilos_random, &thread1_args[0]);
  41.     pthread_create(&thread2_id, NULL, &hilos_random, &thread1_args[1]);
  42.     pthread_create(&thread3_id, NULL, &hilos_random, &thread1_args[2]);
  43.     pthread_create(&thread4_id, NULL, &hilos_random, &thread1_args[3]);
  44.     pthread_create(&thread5_id, NULL, &hilos_random, &thread1_args[4]);
  45.  
  46.     pthread_join(thread1_id, NULL);
  47.     pthread_join(thread2_id, NULL);
  48.     pthread_join(thread3_id, NULL);
  49.     pthread_join(thread4_id, NULL);
  50.     pthread_join(thread5_id, NULL);
  51.  
  52.     int total = 0;
  53.     for (i = 0; i < 5; i++)
  54.     {
  55.         total += aleatorios[i];
  56.     }
  57.  
  58.     printf("Suma de los números: %d \n", total);
  59.  
  60.     return 0;
  61. }

Pero es bastante sencillo:
Lecturas concurrentes si puedes.
Escrituras concurrentes solo uno a la vez.

Existen escenarios peores como deathlocks, donde te quedas esperando a que X thread termine pero ese X thread esta esperando a que tu termines.

También escenarios donde dices: Quiero que X se ejecute antes de Y.

Te recomiendo The little book about semaphores