martes, 30 de marzo de 2010

Apuntes clase del martes 30 de marzo

Lanzador de procesos
Inicializa todas las estructuras necesarias para sincronizar, y se encarga de lanzar todos los procesos.

Destructutor
Borra todas las estructuras creadas en el sistema.

-----

Las estructuras a utilizar del SO son:

IPC - Interprocess Communication
  • Semáforos del SO
  • Colas de mensajes
  • Memoria compartida
El SO utiliza SIEMPRE todas las estucturas mencionadas arriba.
Todo el esquema de trabajo del IPC sigue la misma estructura que los archivos (file system).

Semáforos

La ventaja de utilizar semáforos en vez de variables de estado, es que estos proveen operaciones atómicas.

Si existe una sección crítica, esta debe protegerse con un semáforo, donominados SEMÁFOROS PARA EXCLUSIÓN MUTUA (MUTEX).

Los semáforos que vamos a utilizar son los mismos que el SO, por ende la primera condición es que se debe trabajar como usuario para no colisionar con dichos semáforos.
Se debe asegurar que el semáforo con el que trabajemos, se encuentre siempre "en blanco".
Así mismo, hay que asegurarse de que el IPC no tenga errores. (El sistema operativo "asume" que los errores son manejados por uno).

Estructura de un proceso



Cuando se lanza un proceso, se copia el USER AREA del proceso "padre".
Los tres primeros file descriptors que hereda, son STDINPUT, STDUOUTPUT, STDERROR.

Para crear un proceso se utiliza "fork" (unix)

Para lanzar N procesos, se realiza una copia del padre, y se reemplaza el código de este por el código del nuevo proceso.

---------------
Por cada IPC se genera una clave numérica
ftok(pathDirectorio, nro);

(En nuestro caso vamos a utilizar el desktop del knoppix, creando un directorio con nuestro apellido - /home/knoppix/Desktop/APELLIDO)

Ejemplo Semáforos:

/**
* Crear un semaforo
*
* @return int // File descriptor
**/
int crearSemaforo(int sem){
key_t clave;
clave = ftok(DIRECTORIO, sem);
return (semget(clave, 1, IPC_CREAT|IPC_EXCL|0660/*Permisos*/));
}

/**
* Tomar un semaforo ya creado
*
* @return int // File descriptor
**/
int getSem(int sem){
key_t clave;
clave = ftok(DIRECTORIO, sem);
return (semget(clave, 1, 0660));
}

/**
* Inicializar semáforo
*
* @param int fd, int val
*
* Val
* 1 - permitido
* 0 - no permitido
**/
int iniSem(int semId, int val) {
  union semu {
    int val;
    struct semid_ds *buf;
    unisgned short *array;
    struct seminfo *_buf;
  } arg;
  arg.val = val;
  return (semctl(semId, 0, SETVAL, arg));
}

/**
* Destruir un semáforo
**/
int elimSem(int semId) {
  return (semctl(semId, 0, IPC_RMID, (struct semid_ds *)0)); // Se castea la estructura a NULL para liberar el área
}

/** crearSemaforo se usa en el lanzador, y en todo lo demas se utiliza getSem **/


Utilizar semáforos:

/**
* Realizar un wait; tomar el semáforo
**/
int P(int semId) {
  struct sembuf oper;
  oper.sem_num = 0; // El primero, en este ejemplo SIEMPRE 0
  oper.sem_op = -1;
  oper.sem_flag = 0;
  return (semop(semId, &oper, 1));
}

/**
* Realizar un signal; liberar el semáforo
**/
int V(int semId) {
  struct sembuf oper;
  oper.sem_num = 0; // El primero, en este ejemplo SIEMPRE 0
  oper.sem_op = 1;
  oper.sem_flag = 0;
  return (semop(semId, &oper, 1));
}

/**
* Mutex
**/
int mutex ;
char mostrar[256];

if ((mutex == crearSem(1)) == -1)
{
  perror("xxx, error al crear el mutex");
  exit(1);
}

/**
* En consola ejecutado como
*
* ./pepe 1
**/

nro = argv[1]; // 1
prog = argv[0]; // pepe
pid = getpid(); // pid del proceso en cuestion

sprintf(mostrar, "%s, (%d) %d mensaje de xx enviado", prog, nro, pid);

// Una vez que este el mensaje creado, necesitamos pasarlo al stdout
write(fileno(stdout), mostrar, strlen(mostrar));

1 comentario:

  1. Buenas! Estoy en la clase de SO2 de Feldgen, dejo mi mail para que me agregues
    drielari@gmail.com

    ResponderEliminar