Técnicas Digitales III
Transcripción
Técnicas Digitales III
Técnicas Digitales III Segundo Cuatrimestre Elaborado por: Pablo Sánchez Año: 2010 Un programa se transforma en proceso cuando se ejecuta y se encuentra en memoria. Este recibe un PID o Process ID. Diferencia entre Proceso y Tarea Procesos: son todos. Tarea: Solo el proceso que está en ejecución. PID – TTY (Consola actual) – Stat (R: activo S: Sleep) – TIME (Tiempo en ejecución del comando) El proceso con R es una tarea. Una de las formas que tienen los procesos para comunicarse entre ellos son las Señales. Existen más formas que las veremos a lo largo de las clases. Una señal es enviada de un proceso a otro que la recibe y la procesa. Veremos a continuación una de las formas de crear procesos, muy utilizada a lo largo del cuatrimestre y muy importante en “Sockets”. Concepto de kill, signal, zombie (wait). Concepto Instrucciones básicas •#include<signal.h> •signal([N° señal], [Nombre de Handler]) •getpid() •getppid() •getpgid() •sleep(1) -> Segundos •kill ([PID apuntado],[N° Señal]) •wait() •Por linea de comandos: kill – [N° señal] [PID] int open(const char *pathname, int flags, mode_t mode); if(!(archivo=open(nombre, O_RDWR | O_CREAT, 0660))) printf("Error de apertura de archivo"); Archivo: file descriptor Nombre: nombre del archivo a abrir. O_RDWR | O_CREAT: Abre en modo lectura escritura y si no existe, lo crea. 0660: atributos owner, group, others. -> read(4), write(2),execute(1). ssize_t read(int fd, void *buf, size_t count); ssize_t write(int fd, const void *buf, size_t count); Ejemplo de write: sprintf(mensaje,"\nHola Mundo\n"); write(archivo,mensaje,256); (…) (…) #include<stdio.h> #include<stdlib.h> #include<signal.h> //Declaro funciones, en este caso, solo la del manejo del handler. void Signal_Handler (int); //Único handler para manipular todas las señales //Declaro variables globales (no se recomienda, pero las necesito para trabajar en las funciones int m=0, Total_Hijos; //Comienzo de Programa int main (int argc, char* argv []) //Acepta parámetros por línea de comandos { //Estas son las señales más comunes, hay más y se pueden utilizar /* signal(10,Signal_Handler); //User signal signal(SIGINT,Signal_Handler); //interrupt teclado signal(14,Signal_Handler); //Fin Child por alarma */ //Dejo solo la señal que utilizo signal(17,Signal_Handler); //Fin Child por aviso al padre //Declaro Variables locales int n, var,PIDgrupo,miPID; n=atoi(argv[1]); //Convierto a entero el numero que se pasa por linea de comandos y lo asigno a n Total_Hijos=n; //n lo uso como variable y Total_Hijos como el parámetro que me pasaron por linea de comandos while (n) { var=fork(); //Forkeo, me devuelve PID -> en padre, 0 -> en hijo, me obliga a hacer un if despues. if (var) { if(Total_Hijos==n) { miPID=getpid(); //obtengo mi PID PIDgrupo=getpgid(); //obtengo el ID del grupo printf("\nPadre: Soy Padre Q con ID=%d, GroupID=%d, y mi hijo es Q con PID=%d, ", miPID,PIDgrupo,var); printf("espero que cierre mi hijo para continuar.\n"); n--; //Decremento cada vez que creo un hijo } } else { sleep(2); //Demoro 2 segundos y me coloco en modo baja energia. printf("\nHijo: Soy hijo de P con ID=%d\n y me estoy cerrando", getpid()); kill(getppid(),17); //Sin este comando mi hijo queda en estado Zombie exit(0); //Cierro al hijo, si no lo cierro, me queda loopeando y me genera otro hijo, o sea, hijo del hijo, y asi sucesivamente, se cuelga linux. } } while(1); } //Comienzo del handler de señales void Signal_Handler (int s) { if (s==17) //Con esta sentencia determino que señal me llegó y si corresponde la ejecuto. { wait(); //Obligatorio para no dejar a tu hijo zombie, se espera que se cierre el hijo. Típica pregunta de examen m++; //Cuento los hijos que se cerraron printf("\nPadre: Se cerraron %d hijo/s de %d\n", m, Total_Hijos); if(m==Total_Hijos) //Cuando llego a la cantidad de hijos que entró por linea de comando cierro al padre, sino queda abierto y lo cierro con Ctrl-C o kill -9 PID { printf("\nMe puedo cerrar, pues se cerraron todos los hijos\n"); exit(0); //el 0 indica que se cerro normalmente, en caso de ser distinto, se cierra en forma anormal, utilizar <stdlib> para evita warnings. } } }