lunes, 19 de abril de 2010

Practica y apuntes

Se encuentra disponible para bajar la práctica y los apuntes de la materia.

Pido disculpas por la demora.

La dirección para bajar el archivo es:
Megaupload: http://www.megaupload.com/?d=C30Y10IB
Rapidshare : http://rapidshare.com/files/377757001/so2.rar.html
MediaFire : http://www.mediafire.com/?fq0tttmywlz

Lo puse en 3 hostings distintos por si llegan a tener problemas con alguno.

Saludos, Nicolás

martes, 6 de abril de 2010

Macro para Imprimir

Acá les dejo una macro que armé para poder imprimir en pantalla sin usar printf.
El código se basa en lo que la profesora escribió en clase, pero evita tener que andar copiando y pegando ese código por todos lados.

A falta de creatividad le puse de nombre printout. Se utiliza de la misma forma que el printf, con cero o más argumentos.

Ej:
printout("Hola mundo!\n");
printout("Mi nombre es %s, Mi PID es %d\n",argv[0],getpid());

Este és el codigo de la macro:

#define BUFFER_LEN 512
#define printout(_str, ...) \
do { \
char _buffer[BUFFER_LEN]; \
sprintf(_buffer, _str, ## __VA_ARGS__); \
write(fileno(stdout), _buffer, strlen(_buffer)); \
} while(0)

Recomiendo copiarla a un header (ej: printout.h) para ser incluido en todos los archivos que lo necesiten. Para que compile bien es necesario incluir los siguientes headers: string.h, stdio.h.

Les dejo también una variante que uso yo, que agrega al string el PID del proceso que llamó a ese printout.

#define BUFFER_LEN 512
#define printout(_str, ...) \
do { \
char _buffer[BUFFER_LEN]; \
sprintf(_buffer, "%6d: " _str, getpid(), ## __VA_ARGS__); \
write(fileno(stdout), _buffer, strlen(_buffer)); \
} while(0)

Cualquier duda que tengan pueden dejar un comentario o preguntarme en clase.

Saludos

miércoles, 31 de marzo de 2010

Copia Knoppix 5.1.1

Chicos,
díganme quienes quieren copias del cd de Knoppix, según escuché hay gente que ya lo tiene.

Saludos

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));

Nuevo blog

Se encuentra disponible el blog para Sistemas Operativos 2 de la Universidad CAECE, correspondiente al primer cuatrimestre del ciclo lectivo 2010.