:EXPORT_HUGO_SECTION: practicas

1 Procesos en Unix/C

Estudia el siguiente programa:

/* PROCESOS */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#define NUM_PROCESOS 5

int I = 0;

void codigo_del_proceso(int id) {
  int i;

  for (i = 0; i < 50; i++)
    printf("Proceso(id=%d): i = %d, I = %d\n", id, i, I++);

  // el id se almacena en los bits 8 al 15 antes de devolverlo al padre
  exit(id);
}

int main() {
  int p;
  int id[NUM_PROCESOS] = {1, 2, 3, 4, 5};
  int pid;
  int salida;

  for (p = 0; p < NUM_PROCESOS; p++) {
    pid = fork();
    if (pid == -1) {
      perror("Error al crear un proceso: ");
      exit(-1);
    } else if (pid == 0) // Codigo del hijo
      codigo_del_proceso(id[p]);
  }

  // Codigo del padre
  for (p = 0; p < NUM_PROCESOS; p++) {
    pid = wait(&salida);
    printf("Proceso(pid=%d) con id = %x terminado y status = %d \n", pid,
           salida >> 8, WEXITSTATUS(salida));
  }
  return 0;
}
  1. Comenta qué se espera que ocurra en cada porción de código y la salida. ¿Qué crees que hace WEXITSTATUS ? ¿Es una función o una macro del preprocesador de C?
  2. Ahora edita y ejecuta un programa de ejemplo con dos procesos concurrentes que impriman en pantalla 1 y 2 respectivamente.
  3. Transforma el código anterior para que definamos una única función a la que se le pase como parámetro el valor entero que se desea imprimir. Instancia a continuación dos procesos que ejecuten dicha función a la que le pasaremos como parámetro un 1 y un 2 respectivamente.
  4. Implementa un programa que contenga una función imprimir que imprima un carácter cualquiera 5 veces. En el programa principal debemos crear 3 procesos concurrentes que impriman, utilizando la función imprimir, una ‘A’, una ‘B’ y una ‘C’ respectivamente.

2 Hilos POSIX

Estudia el siguiente programa:

/*
 * hilos
 * Compilación: cc -o hilos hilos.c -lpthread
 */

#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define NUM_HILOS 5

int I = 0;

void *codigo_del_hilo (void *id){
   int i;
   for( i = 0; i < 50; i++)
      printf("Hilo %d: i = %d, I = %d\n", *(int *)id, i, I++);
   pthread_exit (id);
}

int main(){
   int h;
   pthread_t hilos[NUM_HILOS];
   int id[NUM_HILOS] = {1,2,3,4,5};
   int error;
   int *salida;

   for(h = 0; h < NUM_HILOS; h++){
      error = pthread_create( &hilos[h], NULL, codigo_del_hilo, &id[h]);
      if (error){
        fprintf (stderr, "Error: %d: %s\n", error, strerror (error));
        exit(-1);
      }
   }
   for(h =0; h < NUM_HILOS; h++){
      error = pthread_join(hilos[h], (void **)&salida);
      if (error)
         fprintf (stderr, "Error: %d: %s\n", error, strerror (error));
      else
         printf ("Hilo %d terminado\n", *salida);
   }
}
  1. Si no comprendes bien lo que son los punteros void* presta atención a este vídeo.

  2. Comenta qué se espera que ocurra en cada porción de código y la salida. Comenta a continuación las diferencias más importantes entre este programa y el equivalente con procesos de la sesión 1.

  3. Implementa un programa que contenga una función imprimir que imprima un carácter n veces. A la función se le debe pasar como parámetro una estructura en la que deben ir encapsulados el carácter y n.

    En el programa principal debemos crear 3 hilos concurrentes que impriman una ‘A’ 50 veces, una ‘B’ 100 veces y una ‘C’ 150 veces respectivamente.

3 Entrega

  • Se realiza en pracdlsi en las fechas allí indicadas. Puedes entregar tantas veces como quieras, solo se corrige la ultima entrega.

  • Crea una carpeta llamada p1 y dentro de ella estarán el código y archivos de texto o PDF donde contestas a las preguntas. Esta carpeta la comprimes en un archivo llamado p1.tgz p.e. así usando el terminal:

    tar cfz p1.tgz p1