Introducción

¿Qué es un proceso?
Un proceso es una instancia de un programa en ejecución. Linux es un sistema operativo multitarea y multiusuario por lo que más de una tarea puede estar en ejecución a la vez, si varios usuarios ejecutan un mismo programa desde equipos diferentes habrá cinco instancias del mismo programa es decir cinco procesos distintos. Toda tarea que se está ejecutando en un sistema es un proceso (a excepción del kernel el cual reside en memoria y al que los procesos pueden tener acceso mediante llamadas al sistema).

Los procesos son tareas separadas unas de otras con sus propios derechos y responsabilidades, hacen uso de la CPU del sistema para realizar sus instrucciones, de la memoria para almacenarse a él y a sus datos además de usar ficheros y  hasta los dispositivos conectados.

El recurso más valioso de un sistema es la CPU y si hay más procesos que CPUs estos deben esperar en memoria a que le sea asignado tiempo de computación.  El objetivo de un S.O. como Linux es maximizar su uso de la forma más eficiente a través del control de los procesos.

Para controlar los procesos y los recursos que utilizan mostraremos más adelante una serie de comandos con ejemplos de uso para la administración de nuestro sistema Linux.





Características

1. Propiedades
Un proceso incluye, no sólo el programa que ejecuta, sino toda la
información necesaria para diferenciar una ejecución del programa de otra

  • Identificadores
PID (Process ID): número de referencia único que tiene cada proceso que se inicia. Lo genera el Kernel
UID,GID (User ID, Group ID): usuario y grupo al que pertenece el proceso. Estas determinan los derechos del proceso a acceder a los recursos del sistema y ficheros.
PPID (Parent Process ID): PID del proceso padre
Entorno
Parámetros y varibles con sus correspondientes valores (HOME, PATH, USERNAME, etc)

  • Contexto
El contexto de un proceso está formado por el contenido: de su espacio de direcciones (user), de los registros hardware del procesador y de las estructuras de datos del kernel relativas al proceso. Es decir, el contexto de un proceso es su estado, definido por:
–Su código.
–Los valores de sus variables de usuario globales y de sus estructuras de datos.
–El valor de los registros de la CPU.
–Los valores almacenados en su entrada de la tabla de procesos y en su área de usuario.
–Y el contenido de sus pilas (stacks) de usuario y kernel.


2. Estados de un proceso
Mientras un proceso se ejecuta su estado cambia debido a sus circunstancias:

Running: el proceso se está ejecutando o está listo para ello (esperando a que se le asigne tiempo de CPU)
Waiting: el proceso está esperando un evento o un recurso. Aquí Linux diferencia entre 2 tipos, interrumpible e ininterrumpible. Mientras el primero puede detenerse mediante una señal los ininterrumpibles están esperando a una condición del hardware  no puede ser detenido bajo ninguna circunstancia.
Stopped: el proceso está detenido, usualmente debido a recibir una señal.
Zombie: es un proceso que ha completado su ejecución pero aún tiene una entrada en la tabla de procesos, permitiendo al proceso que lo ha creado leer el estado de su salida

3. Concurrencia
Concurrencia es la capacidad de ejecutar varios procesos de forma simultánea.  Si realmente hay varios a la vez es paralelismo, de otra forma es el S.O. el que genera un paralelismo virtual mediante compartición de recursos.
Los procesos pueden ser concurrentes si pueden ejecutarse en paralelo o secuenciales si se ejecutan uno después de otro (mediante waitpid o mediante eventos.

4. Servicios y funcionalidad
El Sistema Linux nos ofrece un conjunto de funciones (llamadas a sistema) para gestionar los procesos:
Creación, planificación y eliminación de procesos
Bloquear y desbloquear procesos
Mecanismos de sincronización
Mecanismos de comunicación (memoria compartida, dispositivos especial y gestión de señales)

5. Creación de procesos



En Linux se crea un nuevo proceso con una llamada al sistema (fork) del proceso padre. El único que no cumple esto es el proceso 0 (swapper, encargado de la gestión de la memoria virtual) del que se crea el proceso “init”.
El proceso hijo hereda algunos aspectos del padre (espacio de direcciones lógico, tabla de programación de señales, los dispositivos cirtuales, el usuario/grupo y las variables de entorno). No hereda los identificadores, los contadores internos de utilización y las alarmas y señales pendientes.

6. Comunicación entre procesos
Existen 4 formas de comunicación entre procesos en Linux:
A través de variables de entorno: solo es posible de padres a hijos.
Mediante una señal: solo indica que algo ha ocurrido y solo lleva como información de un número de señal.
Mediante entrada-salida: es la forma más corriente a nivel de shell. ejemplo: el operador pipe '|' que conecta dos procesos.
Mediante técnicas IPC u otras: semáforos, memoria compartida, colas de mensajes.

7. Gestión Interna de procesos. PCB y Planificación
Para realizar la gestión de los procesos el sistema Linux necesita:
Estructuras de datos para representar sus propiedades, Process Control Block (PCB)
Estructuras de gestión que organicen los PCB's en función de su estado o necesidades de organización del sistema (genralmente con listas o colas aunque también con otras más complejas como tablas hash, árboles, etc)
Algoritmos de planificación que nos indiquen como gestionar estas estructuras y mecanismos que apliquen las decisiones tomadas por el planificador

Comandos

1. Monitorización de procesos
  • $PS
Sintaxis:    ps [opciones]
Muestra la lista de procesos del sistema y algunas de sus características: hora de inicio, uso de memoria, estado de ejecución, propietario y otros detalles.
Opciones:
-a    Muestra los procesos creados por cualquier usuario y asociados a     un terminal
-l    Formato largo. Muestra prioridad, el PID del proceso padre
-u    Formato de usuario. Incluye el usuario propietario del proceso y la     hora de inicio
-U     usr lista los procesos creados por el usuario “usr”
-x    Muestra los procesos que no están asociados a ningún terminal del     usuario (entre ellos los “daemons”)

  • $PSTREE
Sintaxis:    pstree [opciones] [PID] [user]
Este comando muestra la jerarquía de los procesos mediante una estructura en árbol. Si se especifica un PID de proceso mostrará a partir de este, de lo contrario comienza por el proceso init (PID=1) y mostrará todos los procesos del sistema. Si se especifica un usuario válido se mostrará la jerarquía de todos los procesos del usuario.
Opciones:
-a    Incluye en el árbol de procesos la línea de comandos que se usó     para iniciar el proceso.
-c    Deshabilita la unión de procesos hijos con el mismo nombre     (replicas de un mismo proceso)
-G    Usa los caracteres de línea para dibujar el árbol. La representación     el árbol es mas clara.
-h    Remarca la jerarquía del proceso actual.
-n    Por defecto los procesos con mismo padre se ordenan por el     nombre. Esta opción fuerza a ordenar los procesos por su PID
-p    Incluye el PID de los procesos en el árbol

  • $TOP
Sintasix:    top [opciones]
El comando TOP ofrece una lista de procesos similar al comando ps, pero la salida se actualiza continuamente, especialmente útil cuando es necesario observar el estado de los procesos o comprobar los recursos que consumen.
Opciones
-i    Ignora a los procesos inactivos listando únicamente los que utilizan     recursos del sistema.
-d    Especifica el ritmo de actualización de la pantalla en segundos. Es     posible especificar decimales.
Ordenes:
h    Muestra una pantalla de ayuda
q    Sale del programación
k    Kill. Permite detener un procesos
r    Renice. Permite alterar la prioridad de un proceso

  • $HTOP
De funcionamiento similiar a TOP el comando HTOP ofrece algunas ventajas como la navegación entre procesos, tanto vertical como horizontalmente mediante las flechas en el teclado, una mejora visual   con el añadido de los medidores de consumo de la CPU y una barra inferior con opciones (F1-F10) que permiten entre otras cosas filtrar la información o matar un proceso situándonos sobre el.
Opciones
-s    Ordena por columna
-u    Muestra solo los procesos de un usuario
-p    Muestra solo la informacion de los PIDs introducidos


2. Ejecución en 1º y 2º plano
Un proceso ejecutado en 1º plano se ejecuta bloqueando el terminal desde el que lo lanzó. Se ejecuta simplemente introduciendo su nombre en el terminal y pulsando intro. Con un proceso en 1º plano podemos realizar dos acciones desde el terminal asociado:
-    Matar al proceso: Ctrl-c, se cancela el proceso y se liberan sus recursos asignados. Esta acción envía una señal de interrupción al proceso indicándole que tiene que detenerse. Sólo podemos matar procesos sobre los que tengamos permiso (salvo root)
-    Parar el proceso: Ctrl-z, en este caso sólo se detiene su ejecución, conservando su estado y recursos para poder continuar en el momento que se de la orden “fg”

Un proceso ejecutado en 2º plano no bloquea el terminal desde el que se lanzó. Los programas pueden iniciarse en 2º plano añadiendo el carácter & al final del comando. Cuando un proceso se ejecuta en segundo plano se crea un trabajo (job) al cual se le asigna un número entero empezando por 1 y numerado secuencialmente. La única manera de comunicarse con el proceso es mediante el envio de mensajes (signals).

Se puede mover un programa ejecutado en primer plano al segundo plano deteniéndolo usando Ctrl+z y después reiniciándolo en 2º plano mediante la orden “bg”.


3. Señales a procesos
Cada proceso que se ejecuta en el sistema está alerta de los mensajes enviados por el kernel o el usuario. Se utilizan los comandos kill y killall para enviar estas señales. Existen 30 señales diferentes definidas en Linux. Cada señal tiene un nombre y un entero asociado.

 

  • $KILL
Sintaxis:    kill [-s sigspec | -sigspec] [pids]
El comando kill permite enviar un mensaje a un proceso o varios por sus números PID. El parámetro sigspec es el valor entero de la señal que enviaremos al proceso. Si se omite sigspec en el comando kill se toma por defecto el valor SIGTERM (15, salir de manera correcta).
Ejemplos (comandos equivalentes):
$kill 4515            kill -s TERM 4515
$kill -SIGTERM 4515    kill -s 15 4515
$kill -s 15 4515        kill -s sigterm 4515



  • $KILLALL
Sintaxis:    killall [-s sigspec | -sigspec ] nombreproceso
Esta orden es ligeramente diferente a kill, en primer lugar utiliza el nombre de proceso en lugar del PID y además envía la señal a todos los procesos con el mismo nombre. Por lo demás su comportamiento es idéntico a kill

4. Control de procesos desde el terminal
Cuando lanzamos un proceso en segundo plano obtenemos un PID y un número de trabajo. A diferencia del PID(único) el número de trabajo es un identificador de uno o varios procesos correspondientes a un usuario.

  • $JOBS
Sintaxis:    jobs [options] [jobspec]
Lista todas las tareas activas. Si se incluye jobspec únicamente listará la información sobre esas tareas.
Con la orden jobs podemos obtener una lista de los trabajos que hemos lanzado en el sistema.
Opciones:
-l    Lista los PID de las tareas

  • $FG (foreground)
Sintaxis:    fg [jobspec]
Se utiliza para traer a primer plano un trabjao que está en segundo plano,  esté activo o detenido.
Ejemplo:


  • $BG (background)
Sintaxis:    bg [jobspec]
Mueve el trabajo jobspec a segundo plano como si se hubiser iniciado con “&”. Si el proceso especificado está detenido bg lo reinicia en segundo plano.
Ejemplo:


  • $NOHUP
Sintaxis:    nohup orden [argumentos]
La orden nohup lanza un proceso independiente del terminal que hemos usado. Básicamente lo que hace es ignorar la señal HUP (que se envía a un proceso cuando la terminal que lo controla se cierra).

5. Prioridad de procesos desde el terminal
Cada proceso tiene una determinada prioridad de ejecución, al necesitar más o menos CPU que otros. Normalmente la prioridad de los procesos es gestionada por el kernel automáticamente, no obstante Linux ofrece la posibilidad e modificar estas prioridades.

La prioridad de un proceso puede determinarse examinando la columna PRI en los resultados de los comandos top y ps -l. Los valores mostrados son relativos, cuanto mayor es el PRI mayor es el tiempo de CPU dedicado por el kernel a ese proceso.

El parámetro nice puede tomar valores comprendidos entre -20 y +19. Cualquier usuario puede aumentar el valor de nice y bajar la prioridad del proceso pero únicamente el usuario root puede asignar números negativos a nice y por lo tanto incrementar la prioridad y el tiempo de CPU.

  • $NICE
Sintaxis:    nice [-n nicenumber | -nicenumber] command
El comando nice se usa para iniciar un proceso y proporcionarle un determinado valor. Para los usuarios normales está comprendido entre 1 y 19. Para root los valores pueden tomar entre -20 y 19. Un numero más bajo incrementa la prioridad de ejecución de un proceso.

  • $RENICE
Sintaxis:    renice [+|- nicenumber] [options] targets
Este comando permite modificar el parámetro nice de un proceso ya iniciado.
Opciones:
-i    Interpreta targets como nombre de usuario. Cambia el parámetro nice a todos los procesos propietarios de dicho usuario.
-p    Interpreta targets como PID (por defecto).


Bibliografía

-http://docencia.ac.upc.edu/FIB/grau/SO/enunciados/Teoria/T2-Procesos.pdf
-http://www.thegeekstuff.com/2011/04/ps-command-examples/
-http://www.tldp.org/LDP/tlk/kernel/processes.html
-http://www.ual.es/~acorral/DSO/Tema_2.pdf
-http://elara.site.ac.upc.edu/documentacion/LINUX%20-%20UD7%20-
%20Gestion%20de%20Procesos.pdf
-Amir Afzal: “Introducción a UNIX. Un enfoque práctico”. Prentice Hall