Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: ShadowA7X en 13 Noviembre 2015, 21:59 pm



Título: Pregunta Teorica - Programación C Linux
Publicado por: ShadowA7X en 13 Noviembre 2015, 21:59 pm
Hola chicos! que tal les va? espero que bien. Bueno, les cuento, estoy realizando ejercicios del libro silverchatz de Sistemas Operativos para prepararme para mi evaluación de fin de año. En fin, resulta que uno de los ejercicios que hice era crear un programa en C (linux) que ejemplificara una impresora a la cual le iban llegando diversos trabajos (documentos) a una cola de impresión y estos los debe ir imprimiendo según la prioridad que tengan dichos documentos. Bueno el programa ya lo hice, pero me dejó intrigado la pregunta teórica que viene después de realizar el código:

Que consideraciones hay que tomar si existen varias impresoras disponibles?

En el libro no hay solucionario para esta pregunta y en lo personal, no llego a una respuesta que me convenza. me podrían dar su opinión de cual es la respuesta más acertada?

Acá dejo el código en caso de que no se haya atendido lo anterior.

Código
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <sys/types.h>
  4. #include <stdlib.h>
  5. #include <errno.h>
  6. #include <pthread.h>
  7. #include <semaphore.h>
  8. #define Max_Trabajo 60 // El número máximo de hebras Trabajos.
  9.  
  10.  
  11. // Prototipos de funciones...
  12.  
  13. void *Trabajos(void *num);
  14. void *servidor(void *);
  15. void rango_espera(int secs);
  16.  
  17.  
  18.  
  19. //Se definen los semaforos.
  20. //El semaforo colaimpresion pone el limite del numero de Trabajos que se permiten ingresar al cuarto de espera en un tiempo determinado.
  21. sem_t colaimpresion;
  22. // Ocupar_servidor asegura la mutua exclusividad en el acceso al uso del servidor.
  23. sem_t Ocupar_servidor;
  24. // DescansaServidor es usada para permitir que el servidor descanse hasta que llegue el Trabajo.
  25. sem_t DescansaServidor;
  26. // MantenerTrabajo es usada para hacer que el Trabajo espere hasta que el servidor haya imprimido el documento.
  27. sem_t MantenerTrabajo;
  28. // Bandera para la hebra del servidor cuando todos los Trabajos han sido atentidos.
  29. int Todohecho = 0;
  30. int TrabajosEsperandoServidor=0;
  31. int numEspacios=1;
  32.  
  33. int main(int argc, char *argv[])
  34. {
  35.    int i;
  36.    pthread_t btid;
  37.    pthread_t tid[Max_Trabajo];
  38.    int numTrabajos;
  39.    int Numero[Max_Trabajo];
  40.    printf("El &#324;umero maximo de Trabajos es 60. Ingresa el numero de Trabajos.\n");
  41.  
  42.    do{
  43.    scanf("%d",&numTrabajos);
  44.  
  45.    if(numTrabajos > Max_Trabajo)printf("El nº de Trabajos debe ser menor a %d, ingrese nº de Trabajos.\n",Max_Trabajo);
  46.  
  47.   }while(numTrabajos>Max_Trabajo);
  48.  
  49.    if (numTrabajos > Max_Trabajo) {
  50.       printf("El Maximo numero de Trabajos es %d.\n", Max_Trabajo);
  51.       /******system("PAUSE");*****************/
  52.       getchar();
  53.       getchar();
  54.  
  55.       return 0;
  56.    }
  57.    printf("Tenemos un servidor que imprime documentos.\n");
  58.    for (i = 0; i < Max_Trabajo; i++) {
  59.        Numero[i] = i;
  60.    }
  61.    // Se inicializa el semaforo con valores iniciales...
  62.    sem_init(&colaimpresion, 0, numEspacios);
  63.    sem_init(&Ocupar_servidor, 0, 1);
  64.    sem_init(&DescansaServidor, 0, 0);
  65.    sem_init(&MantenerTrabajo, 0, 0);
  66.  
  67.    // Se Crea el servidor.
  68.    pthread_create(&btid, NULL, servidor, NULL);
  69.  
  70.    // Se Crea el Trabajo.
  71.    for (i = 0; i < numTrabajos; i++) {
  72.        pthread_create(&tid[i], NULL, Trabajos, (void *)&Numero[i]);
  73.    }
  74.    // Se juntan las hebras a esperar que las otras terminen.
  75.    for (i = 0; i < numTrabajos; i++) {
  76.        pthread_join(tid[i],NULL);
  77.    }
  78.    // Cuando todos los Trabajos hayan terminado, se elimina la hebra servidor.
  79.    Todohecho = 1;
  80.    sem_post(&DescansaServidor); // Se despierta al servidor en la salida.
  81.    pthread_join(btid,NULL);
  82.    getchar();
  83.    getchar();
  84.    return 0;
  85. }
  86.  
  87. void *Trabajos(void *Numero) {
  88.     int num = *(int *)Numero; // periodo de tiempo aleatorio para llegar.
  89.     printf("hebra %d creada\n", num);
  90.     rango_espera(5);
  91.     if(numEspacios+1==TrabajosEsperandoServidor)printf("Trabajo %d intenta ingresar a la cola de impresion\nEl Trabajo desiste de ingresar a la cola porque hay muchos trabajos\n", num); // Espere hasta que sea prudente ingresar a la cola de impresion...
  92.     sem_wait(&colaimpresion);
  93.    printf("Trabajo %d intenta ingresar a la cola de impresion \nTrabajo %d entra a la cola de impresion.\n************************************Hay %d Trabajos esperando a ocupar el servidor \n", num, num,++TrabajosEsperandoServidor); // Esperar a que el servidor este libre..
  94.  
  95.     //printf("*****************************************\n");
  96.    // printf("**Hay %d Trabajos en la cola de impresion      **\n",TrabajosEsperandoServidor);
  97.    // printf("*****************************************\n");
  98.     sleep(10);
  99.     sem_wait(&Ocupar_servidor); // Si el servidor está libre entonces un trabajo aprovecha.
  100.     sem_post(&colaimpresion); // Despierta el servidor...
  101.     printf("Trabajo %d ocupa el servidor.\n", num);
  102.     sem_post(&DescansaServidor); // Espera a que el servidor termine de imprimir el trabajo.
  103.     sem_wait(&MantenerTrabajo); // Deja de ocupar el servidor.
  104.     sem_post(&Ocupar_servidor);
  105.   printf("Trabajo %d deja de ocupar el servidor.\n************************************Hay %d Trabajos intentando ocupar el servidor\n", num,--TrabajosEsperandoServidor);
  106.  
  107.    // printf("*****************************************\n");
  108.    // printf("**Hay %d Trabajos en la cola de impresion **\n",TrabajosEsperandoServidor);
  109.     //printf("*****************************************\n");
  110.     sleep(10);
  111. }
  112.  
  113. void *servidor(void *junk)
  114. {
  115. // Mientras todavía hayan Trabajos que atender... El servidor es omniciente y puede decir si hay Trabajos aún en el camino a su tienda.
  116.  
  117.  while (!Todohecho) { // Esperar hasta que alguien llegue y te despierte..
  118.    if( TrabajosEsperandoServidor==0 ) printf("el servidor esta esperando\n");
  119.    sem_wait(&DescansaServidor); // Omitir todo esto al final...
  120.    if (!Todohecho)
  121.    { // Tomar un monto aleatorio de tiempo para imprimir el Trabajo..
  122.     printf("el servidor esta imprimiendo el documento\n");
  123.     rango_espera(3);
  124.     printf("el servidor ha terminado de imprimir el documento.\n"); // Se libera al Trabajo cuando se haya imprimido el documento...
  125.     sem_post(&MantenerTrabajo);
  126.    }
  127.    else {
  128.         printf("El servidor ha terminado con la cola de impresion.\n");
  129.    }
  130.   }
  131. }
  132.  
  133. void rango_espera(int secs) {
  134.     int len = 1; // Se genera un numero arbitrario...
  135.     sleep(len);
  136. }
  137.  
  138.  

Gracias de Antemano!


Título: Re: Pregunta Teorica - Programación C Linux
Publicado por: furciorifa en 15 Noviembre 2015, 05:09 am
Lo que tendrías que hacer precisamente es una cola de prioridades una estructura de datos muy importante veo que no utilizas arreglos de forma dinámica, con el macros haces escalable los 60 trabajos, pero podrías hacer dinámica la cantidad de trabajos con malloc, y con varias impresoras sería usar una cola que conforme vayan llegando las ordenes de impresión se vaya imprimiendo por eso se FIFO (First In First Out), con estructuras de datos podrías resolver fácil esto.