PROCESOS Y SENIALES =================== Un proceso a diferencia de un programa es algo vivo. Un programa puede dar lugar a varios procesos. A cada proceso le correspondera un numero PID que le identifica totalmente. Cuando arranca el sistema se desencadena una se- ciencia de procesos es la siguiente. Primero se carga el nucleo de unix (KERNEL) de una forma totalmente especial y distinta a otros procesos. Dependiendo de los sitemas puede existir un proceso con PID=0 planificador, o swapper. En casi todos los sistemas seguira un proceso llamadi 'init'. El proceso init tiene PID = 1. Lee un fichero llamado inittab donde se relacionan una serie de procesos que deben arrancarse para permanecer activos todo el rato (demonios). Algunos estan definidos para que en caso de morir sean arrancados de nuevo inmediatamente. Cuando un proceso muera antes que sus hijos, estos seran adoptados por el proceso 'init'. La unica forma de generar un proceso en unix es mediante la llamada al sistema fork(). El Proceso init realizara varios forks y generara procesos con pid>1. En algunos sistemas los numeros de PID van aumentando secuencialmente. En otros resulta un numero impredecible. Entre los procesos generados por init estan los procesos 'getty'. Se arrancara uno por cada terminal. Este proceso setea la velocidad del terminal, manda un saludo y luego lanza el proceso 'login'. Todos esto procesos se ejecutan con EUID y UID = 0, es decir como superusuario. Cuando el proceso conoce nuestra identidad despues de validar usuario password arrancara la shell especificada para nuestro usuario en el propio fichero de passwords. Comando ps Muestra los procesos activos. Se mencionan algunos ejemplos pero hay muchas mas opciones. Consultar man ps. ejemplos: # Procesos de usuario 'dacs' $PS1> ps -u dacs # Procesos del grupo 'argenta' $PS1> ps -g argenta # Procesos ligados al terminal 'tty02' $PS1> ps -t tty02 # Informacion de todos los procesos $PS1> ps -e | more # Informacion larga seleccionando solo aquellas lineas # que contengan la palabra 'find'. $PS1> ps -l | grep find Comando kill Este comando se utiliza para matar procesos. En realidad envia seniales a otros procesos, pero la accion por defecto asociada a la mayoria de las seniales de unix es la de finalizar el proceso. Un proceso unix puede capturar cualquier senial excepto la senial 9. Una vez capturada la senial se puede activar una rutina que puede programarse con toda libertad para realizar cualquier cosa. kill por defecto es kill -15 envia un SIGTERM y provoca cierre ordenado de ficheros. Puede ser ignorado, o puede ser utilizado como un aviso para terminar ordenadamente. Para matar un proceso resulta recomendable enviar u kill -15 y si no se consigue nada repetir con kill -9. Este ultimo -9 envia SIGKILL que no puede ser ignorado, y termina inmediatamente. Solo fallara si no tenemos permisos para matar ese proceso, pero si es un proceso nuestro,, kill -9 resulta una opcion segura. Ejemplo: # Enviar senial SIGTERM al proceso 1625 $PS1> kill 1625 # Comprobar si sigue vivo. $PS1> ps -p 1625 # Si sigue vivo lo matamos definitivamente con SIGKILL. $PS1> kill -9 1625 Comando nice Existen dos numeros de prioridad. La prioridad NICE y la prioridad concedida por el Kernel mediante un algoritmo. Esta ultima no tiene porque coincidir con nice y puede valer mas de 39. En cambio el comando nice solo acepta valores comprendidos entre 0 y 39, siendo 20 el valor por defecto. Cuando nice sube el valor significa que el proceso tiene baja prioridad. nice -10 incrementara el valor nice en 10. Para bajar el valor de nice hace falta permisos de superusuario (Incrementaria la prioridad). uso: nice [-num] comando Comando renice Sirve para cambiar la prioridad de un proceso. Sigue la misma filosofia que el comando nice pero hay que identificar el o los procesos que deseamos cambiar su prioridad. Se puede cambiar la prioridad de un proceso concreto dado su PID o los procesos de un usuario dando su UID o todos los procesos pertenecientes a un determinado grupo. dando su GID. uso: renice [-n offset] [-g | -p | -u] ID Ejemplos: # Ejecutar el comando ps con la minima prioridad. $PS1> nice -39 ps -l # Ejecutar el comando ps aumentando la prioridad (bajando su valor nice) en 10. Esto solo lo puede hacer 'root'. $PS1> nice --10 ps -l # Bajar la prioridad de el proceso 33432 renice -p 33432 Explicacion: En UNIX el multiproceso esta implementado concediendo ciclicamente la CPU en rodajas de tiempo a cada proceso que esta en ejecucion. Para ello para cada proceso en ejecucion existe un contador que se va decrementando en cada intento de acceder a la CPU y solo accedera cuando el contador alcance el valor 0. En ese momento se ejecuta el proceso y el contador se inicializa de nuevo con el valor NICE. Por eso si un proceso tiene un valor NICE bajo, se ejecutara mas veces que uno que tenga un valor NICE alto pero en cualquier caso esta garantizado que todos se ejecutan. Si un proceso tiene valor NICE 0. Se ejecutara todas las veces en cada ciclo. Comando time: Es una buena herramienta de programacion. Da los tiempos de ejecucion. Este comando nos da tres valores cuya interpretacion es: real Tiempo real gastado user Tiempo de usuario. sys. Tiempo consumido como proceso de kernel. (Dentro de las llamadas al kernel) Ejemplo : $PS1> time find / -name unix* -print Todos los procesos son creados por otro que generalmente se considera como proceso padre. Si un proceso queda huerfano sera heredado por el proceso init PID=1. Cuando un proceso muere envia seniales al proceso padre y otras seniales distintas a sus procesos hijos. Cuando los procesos reciben una seņial pueden ejecutar una rurtina o si no existe dicha rutina se ejecutara la accion por defecto que generalmente es terminar. La shell cuando termina envia una senial a los procesos arrancados por ella. Esto hace que terminen. para evitar esto se utiliza el comando nohup. Los procesos tienen un EUID (Efectiv User Identif), y un UID normalmente ambos coinciden. Sin embargo existe un bit de permisos que cuando esta presente en un fichero ejecutable hace que cambie el EUID del proceso convirtiendose en el UID del owner del fichero ejecutable. Gracias a esto un usuario puede tomar temporalmente privilegios de superusuario para acceder por ejemplo a ficheros del sistema propiedad de root. La forma en que un proceso arranca a otro es mediante una llamada al sistema con la funcion fork() y el proceso hijo ejecuta luego una llamada exec() que no retorna nunca. Los demonios son procesos que permanecen arrancados todo el tiempo. Generalmente son iniciados por el proceso init cuando arranca el sistema. Algunos de ellos resucitaran inmediatamente en caso de morir. Un proceso puede pasar al proceso hijo una serie de variables pero un hijo no puede pasar nada a su padre a traves de variables. Las formas de comunicacion entre procesos son: 1) A traves de variables: Solo de padres a hijos. 2) Mediante una senial: Solo indica que algo ha ocurrido no lleva informacion sino solo un numero de seņal. 3) Mediante entrada salida: Es la forma mas corriente a nivel de shell. 4) Mediante sofisticadas tegnicas IPC u otras: Semaforos, Memoria compartida, Colas de mensages.