elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado:


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Pequeña ayudita porfavor (threads/hilos) :)
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Pequeña ayudita porfavor (threads/hilos) :)  (Leído 4,040 veces)
Thorn14

Desconectado Desconectado

Mensajes: 4


Ver Perfil
Pequeña ayudita porfavor (threads/hilos) :)
« en: 9 Enero 2014, 19:15 pm »

Hola, buenas a todos!

Tengo un problemilla con este programa.

Tengo que hacer que de como resultado el numero pi pero no se que hago mal que las interaciones no me funcionan correctamente (algunos numeros se repiten) y hace que el proceso falle. Esta hecho con threads. Cualquier ayuda sera bienvenida!
Código
  1. # include <stdio.h>
  2. # include <stdlib.h>
  3. # include <string.h>
  4. # include <unistd.h>
  5. # include <pthread.h>
  6. double factores [1000];
  7. int i,N;
  8. double step,x, totalsum, pi;
  9.  
  10. void *calcularsum (void *argument){
  11. x = (i+0.5)*step;
  12. factores[i] = 4.0/(1.0+x*x);
  13. }
  14.  
  15. int main (int argc, char *argv[]) {
  16. if (argc != 2){
  17. printf("Se ha de introducir un valor. Ejemplo: ./pi 10\n");
  18. }else{
  19. N=atoi(argv[1]);
  20. step = 1.0/N;
  21. pthread_t h[N];
  22.  
  23. for (i=0; i<N; i++) {
  24. pthread_create(&h[i] , NULL , calcularsum , NULL);
  25.  
  26. }
  27. for (i=0; i<N; i++){
  28. pthread_join(h[i], NULL);
  29. totalsum = factores[i] + totalsum;
  30. printf("%f\n",totalsum);
  31. }
  32. pi = totalsum * step;
  33. printf("%.10f\n", pi);
  34. }
  35. return 0;
  36. }
  37.  
Al hacer el "printf("%f\n",totalsum); " para comprobar que numeros van haciendo los diferentes threads, me encuentro con que alguna vez (random) la hace bien, pero lo mas normal es que el primer número salga como 0.000000 y/o algunos otros se repitan.

El resultado de ejecucion seria:
./pi 10
0.000000
3.911980
7.676686
7.676686
11.003090
14.074107
16.886058
19.446058
21.768264
23.870761
2.3870760525

En cambio otra vez, es un número mas aproximado a pi:
./pi 10
3.990025
7.902005
11.666711
15.230186
18.556589
21.627606
24.439557
26.999557
29.321763
31.424260
3.1424259850


« Última modificación: 9 Enero 2014, 21:35 pm por Thorn14 » En línea

ivancea96


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: Pequeña ayudita porfavor (threads/hilos) :)
« Respuesta #1 en: 9 Enero 2014, 21:09 pm »

Pon etiquetas de código GeSHi de C o C++ y comentarios en el código para mayor comprensión.


En línea

Thorn14

Desconectado Desconectado

Mensajes: 4


Ver Perfil
Re: Pequeña ayudita porfavor (threads/hilos) :)
« Respuesta #2 en: 9 Enero 2014, 21:37 pm »

La cosa es que no se si los pthread_create y pthread_join estan hechos correctamente, no domino mucho de hilos
En línea

ivancea96


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: Pequeña ayudita porfavor (threads/hilos) :)
« Respuesta #3 en: 9 Enero 2014, 22:11 pm »

Aunque nunca usé esos threads, te puedo dar esto: Info.
Y decirte, que pruebes en un ejemplo a parte más sencillo.
En línea

amchacon


Desconectado Desconectado

Mensajes: 1.211



Ver Perfil
Re: Pequeña ayudita porfavor (threads/hilos) :)
« Respuesta #4 en: 9 Enero 2014, 22:20 pm »

El problema que veo ahí es:
Código
  1. x = (i+0.5)*step;
  2. factores[i] = 4.0/(1.0+x*x);

Mientras un hilo está modificando la variable x, mientras otros hilos lo están usando. Si tienes suerte y se sincronizan bien pues te sale, pero como modifiques esa variable x mientras lo está usando el otro hilo... O te sale mal el resultado o en algún caso extremo tu progama podría hacer un abort.

Puedes ponerte un mutex para un acceso sincronizado pero, creo que sería más eficiente evitar variables globales que puedan dar colisión. He aquí mi propuesta:
Código
  1. #include <stdio.h>
  2. #include <pthread.h>
  3.  
  4. double factores [1000],step;
  5.  
  6. void *calcularsum (void *argument)
  7. {
  8.    int i = *((int*) argument);
  9.    double x = (i+0.5)*step;
  10.    factores[i] = 4.0/(1.0+x*x);
  11.    free(argument);
  12. }
  13.  
  14. int main (int argc, char *argv[])
  15. {
  16.    int* P;
  17.    int N,i;
  18.    double totalsum,pi;
  19.  
  20.    if (argc != 2)
  21.    {
  22.        printf("Se ha de introducir un valor. Ejemplo: ./pi 10\n");
  23.    }
  24.    else
  25.    {
  26.        N=atoi(argv[1]);
  27.        step = 1.0/N;
  28.        pthread_t h[N];
  29.  
  30.        for (i=0; i<N; i++)
  31.        {
  32.            P = (int*)malloc(sizeof(int));
  33.            *P = i;
  34.            pthread_create(&h[i] , NULL , calcularsum ,P);
  35.  
  36.        }
  37.        for (i=0; i<N; i++)
  38.        {
  39.            pthread_join(h[i], NULL);
  40.            totalsum = factores[i] + totalsum;
  41.            printf("%f\n",totalsum);
  42.        }
  43.        pi = totalsum * step;
  44.        printf("%.10f\n", pi);
  45.    }
  46.    return 0;
  47. }

No tengo linux a mano ahora, pero debería funcionar.
« Última modificación: 9 Enero 2014, 22:26 pm por amchacon » En línea

Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar
Thorn14

Desconectado Desconectado

Mensajes: 4


Ver Perfil
Re: Pequeña ayudita porfavor (threads/hilos) :)
« Respuesta #5 en: 9 Enero 2014, 23:31 pm »

Si, modificando lo que has comentado, no pasa lo que comentaba. Muchas gracias, ya había pensado también en que podría ser un problema de variables.

Si no es mucha molestia, me podrías explicar que hace las siguientes lineas que has comentado:

Código
  1.    int i = *((int*) argument);
  2.  
  3. P = (int*)malloc(sizeof(int));
  4.            *P = i;
  5.  
En línea

amchacon


Desconectado Desconectado

Mensajes: 1.211



Ver Perfil
Re: Pequeña ayudita porfavor (threads/hilos) :)
« Respuesta #6 en: 10 Enero 2014, 01:25 am »

Citar
int i = *((int*) argument);
argument es un puntero void, si quiero guardarlo en un entero primero tengo que hacerle un cast a puntero int* y después obtener el valor del entero con un *.

Para profundizar más, mirate explicaciones de punteros en C. Por cierto, son muy importantes.

Citar
P = (int*)malloc(sizeof(int));

malloc reserva memoria de forma dinamica, he aquí una explicación de memoria dinámica:
http://foro.elhacker.net/programacion_cc/duda_memoria_dinamica_en_c-t391783.0.html

Ahí uso el new de C++, pero es lo mismo. Después de reservar la memoria guardo un puntero en P, previamente hay que hacer un cast a (int*) ya que P es un puntero a entero.

Citar
*P = i;

P es un puntero, para cambiarle el valor a su contenido tengo que usar el operador *
En línea

Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar
Thorn14

Desconectado Desconectado

Mensajes: 4


Ver Perfil
Re: Pequeña ayudita porfavor (threads/hilos) :)
« Respuesta #7 en: 10 Enero 2014, 08:24 am »

Todo listo, muchas gracias por su tiempo y sus explicaciones.
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Una pequeña ayudita :)
Ejercicios
yrrtni 0 3,093 Último mensaje 25 Octubre 2008, 14:52 pm
por yrrtni
Hilos Threads
Java
pastafariana 0 1,618 Último mensaje 12 Marzo 2013, 20:12 pm
por pastafariana
Duda sobre threads (hilos) y semáforos (mutex)
Programación C/C++
IngenieroFrustrado 3 2,973 Último mensaje 25 Enero 2014, 11:17 am
por amchacon
Duda con threads o hilos
Java
.:UND3R:. 1 2,402 Último mensaje 14 Febrero 2014, 17:59 pm
por Gh057
Threads, Hilos en C++
Programación C/C++
Ahustinkrone 5 10,834 Último mensaje 17 Junio 2014, 16:10 pm
por daryo
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines