Ver Mensaje Individual
  #1 (permalink)  
Antiguo 07/10/2011, 04:21
lomasdelicioso
 
Fecha de Ingreso: diciembre-2010
Mensajes: 52
Antigüedad: 13 años, 5 meses
Puntos: 5
Desacuerdo No sé que hacer ya con este código...

Hola foreros del web, estoy programando en 'c' y tengo un problema porque lo que quiero que me haga este código no me lo hace, he usado el ddd y no veo el problema, es un poco engorroso ver que hace mi código pero se lo agradecería mucho al que fuera capaz.

Se trata de un programa concurrente en el que uso un cerrojo donde una hebra saca recursos de una estructura enlazada y el main mete recursos en la misma estructura, para que no lo hagan a la vez uso el cerrojo.

Código C:
Ver original
  1. /*
  2.  * miPrograma.c
  3.  * Esta version usa una única hebra servidora, que extrae el primer elemento de la
  4.  * lista de peticiones. main inserta nuevas peticiones en la lista, en el orden de menor
  5.  * tiempo de aviso La lista está protegida por mutex, y la hebra servidora se suspende al  
  6.  * menos  1 segundo, en cada iteración, para asegurar que la hebra main tenga oportunidad
  7.  * de bloquear el mutex e insertar una nueva petición a la lista.
  8.  */
  9.  
  10. #include <pthread.h>
  11. #include <time.h>
  12. #include <errno.h>
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <stdlib.h>
  16.  
  17. typedef struct paquete_control {
  18.   struct paquete_control       *enlace;
  19.   int                          segundos;
  20.   time_t                       tiempo;                              // segundos desde EPOCH
  21.   char                         mensaje[64];
  22. } paquete_control_t;
  23.  
  24. pthread_mutex_t lista_mutex = PTHREAD_MUTEX_INITIALIZER;        // Creación del cerrojo
  25. paquete_control_t *lista_pet = NULL;
  26.  
  27. FILE  *fp;  // para guardar la impresion de los avisos, asi la salida del
  28.                   // programa no interfiere con la entrada de peticiones.
  29.  
  30. /*
  31.  * funcion que ejecuta la hebra servidora de avisos.
  32.  */
  33. void *servidora (void *lista_pet)
  34. {
  35.     paquete_control_t *pcontrol;        // Esto es un puntero a un paquete de control
  36.    
  37.    
  38. int sleep_time;
  39. int estado;
  40.     time_t ahora;    
  41.  
  42.   /*
  43.    * La hebra cicla siempre, procesando peticiones del usuario.
  44.    * La hebra sera "desintegrada" cuando el proceso termine.
  45.    */
  46.     while (1) {
  47.    
  48.         estado= pthread_mutex_lock(&lista_mutex);       // bloquear el cerrojo lista_mutex
  49.      
  50.                 if (estado !=0) fprintf(stderr, "Error al bloquear lista_mutex\n"),exit(0);
  51.  
  52.      // asignar el puntero a la direccion de comienzo de "lista_pet"
  53.         pcontrol = (paquete_control_t*)lista_pet;
  54.  
  55.      
  56.     /* Si "lista_pet" esta vacia, asigno a "sleep_time" 1 segundo. La
  57.      * suspension durante 1 s. le permitirá a "main" ejecutarse, e intentar
  58.      * obtener otra peticion del usuario; si no (la lista de peticiones
  59.      * no esta vacia), extraer su primer elemento */
  60.         if (pcontrol == NULL){
  61.             sleep_time = 1;
  62.         }
  63.  
  64.         else{
  65.             lista_pet = pcontrol->enlace;
  66.             ahora = time(NULL);
  67.             if (pcontrol->tiempo <= ahora) sleep_time = 0;
  68.        
  69.             else sleep_time = pcontrol->tiempo - ahora;
  70.         }
  71.  
  72.  
  73.     /* Ahora, desbloquear "lista_mutex", antes de que la hebra "servidora"
  74.      * se suspenda, para que "main" pueda bloquearlo para insertar una nueva
  75.      * peticion del usuario,
  76.      */
  77.         estado= pthread_mutex_unlock(&lista_mutex);
  78.         if (estado !=0) fprintf(stderr, "Error al desbloquear lista_mutex\n"),exit(0);
  79.  
  80.      
  81.  
  82.     /* Si "sleep_time" > 0, entonces suspender la hebra durante
  83.      * ese tiempo; si no, llamar a sched_yield(), y de
  84.      * esta forma darle una oportunidad a "main" de ejecutarse,
  85.      * si tiene una entrada pendiente del usuario, sin retrasar la
  86.      * impresion del aviso si no existiera tal entrada.
  87.      */
  88.         if (sleep_time >0) sleep (sleep_time);
  89.    
  90.         else sched_yield();
  91.      
  92.         if (pcontrol != NULL){
  93.             fprintf(fp, "(%d) %s {%ld} \n", pcontrol->segundos, pcontrol->mensaje,
  94. pcontrol->tiempo);
  95.             free(pcontrol);
  96.         }
  97.      
  98.     }
  99. }
  100.  
  101.  
  102.  
  103. int main (int argc, char *argv[])
  104. {
  105.     int estado;  
  106.     char linea[128];
  107.  
  108.      // declaro punteros para recorrer "lista_pet"
  109.     paquete_control_t  *pcontrol,*aux,*aux2;
  110.  
  111.  
  112.     pthread_t hebraServidora;
  113.  
  114.  
  115.     if ((fp = fopen("Salidas", "w")) == NULL)
  116.         fprintf(stderr, "Error en la apertura del fichero de salida\n"),exit(0);
  117.      
  118.     if (pthread_create(&hebraServidora,NULL,servidora,(void *)lista_pet))
  119.         fprintf(stderr, "Error al crear la hebra servidora\n"),exit(0);
  120.        
  121.     while (1) {
  122.         printf ("Peticion de aviso> ");
  123.         if (fgets (linea, sizeof (linea), stdin) == NULL) exit (0);
  124.         if (strlen (linea) <= 1) continue;
  125.  
  126.     pcontrol= (paquete_control_t*) malloc(sizeof(paquete_control_t));
  127.  
  128.         if ( sscanf(linea, "%d %64[^\n]", &pcontrol->segundos, pcontrol->mensaje) < 2 ){
  129.             if (pcontrol->segundos==-1) break; 
  130.            
  131.             else{
  132.                 fprintf(stderr, "Entrada erronea\n");
  133.                 free(pcontrol);
  134.             }
  135.         }
  136.         else {
  137.                 fprintf(fp, "(%d) %s\n", pcontrol->segundos,pcontrol->mensaje);
  138.             estado= pthread_mutex_lock(&lista_mutex);
  139.  
  140.             if (estado !=0) fprintf(stderr, "Error al bloquear lista_mutex\n"),exit(0);
  141.  
  142.             pcontrol->tiempo=time(NULL);
  143.      
  144.          /*
  145.          * Insertar delante del primer  elemento de  "lista_pet" que tenga
  146.          * un tiempo de aviso >= que el de la nueva peticion que vamos a insertar.
  147.          */
  148.  
  149.             if (lista_pet != NULL){
  150.                 for (aux=lista_pet ; aux->enlace != NULL ; aux=aux->enlace){
  151.                     if (pcontrol->tiempo < aux->tiempo){
  152.                         pcontrol->enlace=aux;
  153.                         aux2->enlace=pcontrol;
  154.                     }
  155.                     aux2=aux;
  156.                         }
  157.                 if (aux->enlace == NULL){
  158.                     aux->enlace = pcontrol;
  159.                     pcontrol->enlace = NULL;
  160.                 }
  161.             }
  162.             else
  163.                 lista_pet=pcontrol;
  164.  
  165.             estado= pthread_mutex_unlock(&lista_mutex);
  166.             if (estado !=0) fprintf(stderr, "Error al desbloquear lista_mutex\n"),exit(0);
  167.         }
  168.  
  169.     }
  170.  
  171.     if (fclose(fp)) fprintf(stderr, "Error al cerrar el fichero\n");
  172. }

Gracias a todos los forer@s del web.