Procesos y tareas

Indicadores de Logros

Lectura: Procesos y tareas

Un sistema Linux típico puede prestar muchos servicios simultáneamente, puede ser servidor de web, al tiempo que es servidor de correo electrónico, puede atender varios usuarios y cada usuario puede estar realizando simultáneamente diversas acciones. Por esto Linux es llamado un sistema multitarea.

A cada acción en un sistema Linux se le llama proceso. Un proceso abstrae una acción que el sistema debe realizar, independiente del momento en que debe ejecutarse. En esta sección se explica como puede controlar procesos y como puede aprovechar al máximo las capacidades multitarea de Linux, por ejemplo realizando diversas labores simultáneamente, o haciendo que la ejecución de un programa continúe después de que usted cierra su sesión (por ejemplo si se trata de un programa que debe correr durante varias horas o días), o incluso programando el inicio de procesos en momentos en los que usted no tiene una sesión abierta (por ejemplo durante la noche --claro está mientras el computador esté encendido a la hora que programe la tarea).

Abstracción de una labor que el sistema debe realizar, un comando creará al menos uno de estos, pueden recibir señales enviadas por el comando kill.

Procesos

Cada proceso tiene asociado un número que lo identifica, un estado que indica como está operando, un grupo que lo asocia con otros procesos, una prioridad que determina su "importancia" con respecto a otros procesos y un dueño que puede controlarlo (normalmente el dueño es el usuario que inicia el proceso). Todos los procesos comparten el procesador ---su computador normalmente tendrá un solo procesador---, para lograrlo, cada proceso emplea el procesador durante un intervalo corto de tiempo y después duerme [1] o se bloquea para dar posibilidad a otro proceso de emplearlo (el orden en el que se ejecutan depende de la prioridad de cada proceso). Normalmente junto con cada programa iniciado por el usuario se inicia un proceso [2], que a su vez puede iniciar otros procesos formando así un árbol; puede examinar tal árbol con el programa pstree. Existen también procesos que no son iniciados explícitamente por un usuario, por ejemplo procesos iniciados durante el arranque del sistema o por X-Window, tales procesos generalmente pueden ser controlados sólo por el administrador del sistema ---quien también podría controlar los procesos de los usuarios.

Comando para ver el árbol de procesos

Cada programa o tubería que inicie desde el intérprete de comando se ejecutará en un nuevo proceso que por defecto estará en primer plano [3] , es decir que bash suspenderá su ejecución y la reanudará cuando el programa que inició termine. Si desea iniciar un programa (o una secuencia de programas unidos por tuberías) en segundo plano [4] , agregué al final del comando un espacio y el carácter '&'. Esto es útil cuando debe ejecutar un programa no interactivo que toma bastante tiempo en completarse, porque mientras la ejecución del programa se completa puede continuar trabajando en el intérprete de comandos ---el programa que inicie se ejecutará en segundo plano mientras bash continua ejecutándose en primer plano. Por ejemplo la conversión de DVI a PostScript (ver Sistemas para preparar documentos) de un documento grande puede tomar bastante tiempo, para realizar la labor en el fondo puede emplear:


dvi2ps -o salida.ps entrada.dvi &

o aún mejor redireccionando salida estándar a archivos para que no se mezclen con su sesión con bash (error estándar sigue redireccionado a consola así que verá en su sesión con bash los errores que puedan producirse):


dvi2ps -o salida.ps entrada.dvi >log  &

Cuando inicia un programa (o una tubería) en segundo plano, bash reanuda su ejecución inmediatamente, presenta el número de tarea que asignó al comando y a continuación el número del proceso.

Caracter empleado para indicar que un comando se ejecute en segundo plano,, se pone después del nombre del comando.

Además de pstree, un usuario puede ver sus procesos con el programa ps (con la opción -e, ps muestra todos los procesos del sistema). Junto con cada proceso ps presenta: identificación del proceso; la terminal en la que presenta información, en caso de que funcione de forma interactiva (por ejemplo una consola virtual como tty1 o una terminal de X-Window como pts/0); el estado del proceso y el tiempo que ha usado el procesador ---el resto del tiempo que el proceso haya existido ha estado durmiendo o esperando algún evento o recurso. Para examinar interactivamente los procesos de un sistema pueden emplearse los programas top o gtop, los cuales además de presentar los procesos y refrescar continuamente sus estadísticas, permiten enviar señales a cada proceso (entre otras diferencias top funciona en modo texto mientras que gtop es una aplicación Gnome).

Programa que permite ver los procesos que están desarrollándose.

Señales

En ocasiones usted deseará terminar algún proceso, por ejemplo porque deja de responder o tarda demasiado en completarse; para hacerlo puede emplear el programa kill para enviarle una señal de terminación. Una señal es como un "llamado de atención" que se hace a un proceso en situaciones excepcionales (por ejemplo errores), pueden ser producidas por otros procesos, por el usuario o por el sistema operativo y en la mayoría de los casos conducen a la terminación del proceso que recibe la señal. Hay diversos tipos de señales, cada una tiene un número, un nombre que la identifica y una acción predefinida (que generalmente puede ser cambiada por el proceso). Un usuario puede enviar una señal a un proceso con el programa kill seguido de la señal que enviará y del proceso que la recibirá:


kill -SIGTERM 945

Este ejemplo envía la señal SIGTERM al proceso con identificación 945 (en vez de SIGTERM pudo haberse usado 15 que es el número que corresponde a esa señal). Puede consultar un listado de todas las señales y sus números con kill -l.

Programa empleado para enviar señales a un proceso, por ejemplo permite enviar la señal SIGTERM que termina un proceso.

A continuación se presenta una breve descripción de algunas señales comúnmente empleadas por usuarios:

Señal empleada para solicitar la terminación de un proceso, su número es 15.

Señal empleada para terminar un proceso de forma inmediata, su número es 9

Señal generada cuando un usuario emplea las secuencia de teclas Control-C para terminarlo.

Señal generada cuando un usuario emplea las secuencia de teclas Control-\ para terminarlo y generar una volcado de memoria.

Señal generada cuando un usuario emplea la secuencia de teclas Control-z para suspender temporalmente la ejecución de un programa.

Señal que se envia a un proceso para que reanude su ejecución, despues de haberla suspendido con SIGTSTP.

Señal que por defecto es enviada al salir de bash a todos los procesos que se ejecutan en segundo plano para terminarlos ---aunque puede iniciarse un proceso que la ignore con nohup.

15 SIGTERM

Esta señal solicita la terminación del proceso que la recibe.

9 SIGKILL

Esta señal termina el proceso que la recibe de forma inmediata. Empleela sólo para detener procesos que no terminan con la señal SIGTERM.

2 SIGINT

Es la misma señal que se produce cuando un usuario en un programa interactivo presiona, Control-C para solicitar su terminación.

3 SIGQUIT

La misma señal producida por Control-\, su efecto es análogo al de SIGINT pero además actúa como si el programa hubiera provocado algún error interno (volcando el contenido de memoria a un archivo core).

20 SIGTSTP

La misma señal producida por Control-z, su efecto es suspender la ejecución de un proceso ---para reanudarla después.

18 SIGCONT

Reanuda un proceso suspendido previamente por la señal SIGTSTP.

1 SIGHUP

Esta señal es enviada por bash a todas las tareas que se ejecutan en segundo plano, cuando el usuario cierra la sesión (por ejemplo al cerrar una terminal en X-Window o cuando sale de su sesión desde una consola virtual). Normalmente un proceso terminará cuando reciba esta señal, pero puede lograrse que el proceso continué (es decir que ignore la señal SIGHUP) si el comando se inició con nohup ---que evita que el programa reciba la señal SIGHUP) o si durante su ejecución se indicó a bash no enviarle esta señal cuando se cierre la sesión, empleando el comando disown. Esto es muy útil cuando debe dejar corriendo un proceso muy demorado (horas o días) mientras usted no tiene una sesión abierta, por ejemplo para ejecutar el programa make [5] en segundo plano, redireccionado salida estándar al archivo sm, error estándar a esm y lograr que continue después de que se cierre la sesión:


nohup make > sm 2> esm &

Control de tareas

Además de las facilidades para controlar procesos que se han presentado en esta sección, bash ofrece "control de tareas". Una tubería o un programa que se ejecute desde bash tiene asociado un número de tarea, diferente al número del proceso. El número de la tarea aparece entre paréntesis cuadrados después de ejecutar un programa en segundo plano. La lista de las tareas de una sesión de bash, puede verse con el comando jobs, por ejemplo allí vera los programas que inició en segundo plano o que haya suspendido con la tecla Control-z. Con el comando fg puede poner en primer plano una tarea que esté en segundo plano, es decir reanudar la aplicación permitiendo que controle la consola mientras que bash se suspende. Por ejemplo si está editando un correo electrónico con mail, suspende la edición con Control-z y después desde bash emplea jobs verá algo como:


[1]+ Stopped          mail amigo@micolegio.edu.co

que indica que el programa mail esta suspendido y su número de tarea es 1. Para bash los números precedidos del caracter '%' indican tareas, así que para reanudar su ejecución en primer plano puede usar:


fg %1

claro que fg le permite emplear el nombre del programa o sus primeras letras en lugar de %1, omitir el símbolo %, o incluso si emplea el símbolo % puede omitir fg. Así que los siguientes comandos son equivalentes al ejemplo anterior:


fg ma
fg 1
%1

Comando que permite ver identificador y nombre de las tareas iniciadas desde una sesión de bash o suspendidas con Control-Z.

Comando que permite poner en primer plano una tarea suspendida o que está en segundo plano.

Otro comando que le permite controlar tareas desde bash es bg el cual le permite ejecutar en segundo plano un programa que está suspendido. Por ejemplo si inicia una impresión de un documento postscript que imprime 2 páginas del original en una con:


a2ps ­­columns=2 documento.ps

puede suspenderla con Control-z, y continuarla en segundo plano con bg - (- es una convención que indica la tarea más reciente) o suponiendo que el número de tarea es 1, con bg %1 o con %1 &.

Comando que permite poner en segundo plano y continuar una tarea suspendida.

Note que cuando suspende un programa con Control-z, la ejecución se suspende, si desea continuarla en segundo plano debe reanudarla en segundo plano con bg.

La tecla Control seguida de esta letra permite suspender la ejecución de un programa, i.e envia la señal SIGTSTP ---puede reanudarse con los comandos fg o bg que envian la señal SIGCONT.

Tiempo

Usted también puede programar cuando ejecutar un proceso con el programa at o eventualmente puede programar eventos periódicos con cron. Antes de introducirlos, describimos algunos programas relacionados con tiempo:

Comando que permite ver la hora del sistema, al administrador le permite también establecerla.

Comando interno de bash para medir el tiempo que un programa requiere para ejecutarse.

Programa que duerme un proceso durante un tiempo, el tiempo (por defecto en segundos) se especifica a continuación del comando.

date

Programa para ver o poner la fecha y hora del sistema (aunque sólo puede ser cambiada por el administrador). Por defecto presenta la hora local de acuerdo a la zona geográfica donde esté el computador que está usando, con la opción -u presenta la hora en el meridiano 0 (i.e tiempo universal coordinado). El administrador puede establecer la fecha y la hora con la opción -s seguida de la fecha y/o hora entre comillas. La información que el comando date presenta puede ser desplegada con un formato diferente con las opciones -I y -R.

time

Es un comando interno de bash, que permite medir el tiempo que emplea la ejecución de un programa. Por ejemplo:


time cat /etc/hosts

ejecuta el programa cat con argumento /etc/hosts y después presenta el tiempo real, de usuario y del sistema que requirió la operación. La diferencia en estos tiempos se debe a las diversas tareas que Linux realiza. Tiempo real se refiere a el tiempo que transcurre desde que se inicia el programa hasta que este termina (sumando tiempos de otros procesos), el tiempo que emplea sólo el proceso es la suma del tiempo de usuario y tiempo del sistema (el primero indica tiempo realizando operaciones fuera del kernel y el segundo tiempo dentro del kernel).

sleep

Este programa duerme el proceso en el que se ejecuta durante un tiempo, por defecto especificado en segundos. Pueden emplearse los posfijos s, m, h y d para indicar segundos, minutos, horas o días. Por ejemplo para dormir un proceso durante 10 segundos sleep 10.

bash puede ejecutar diversos programas y comandos uno después de otro cuando se separan con punto y coma ";", puede aprovechar esto y el programa sleep, para ejecutar tareas después de cierto intervalo de tiempo. Por ejemplo para iniciar la conversión de un documento de PostScript a PDF (ver Sistemas para preparar documentos) 30 minutos después de dar el comando:


sleep 30m ; pdf2ps carta.pdf carta.ps

Sin embargo una mejor forma de iniciar tareas en el futuro es con el comando at. Este comando recibe la hora a la que debe ejecutarse el o los programas que se le den por entrada estándar (puede especificar un archivo con comandos con la opción -f). Por ejemplo:


at 8:40PM today << EOF
pdf2ps carta.pdf carta.ps
EOF

convertirá el documento carta.pdf a formato postscript a las 8:40PM del mismo día. La fecha puede especificarse de muchas maneras, por ejemplo 20:40 20.01.2005 o now+2 hours. Con el comando atq puede ver las tareas programadas y con atrm puede eliminar una tarea especificando el número (el número de cada tarea programada es mostrado por atq). Cuando programa una tarea con at, esta se ejecutará aún cuando usted no tenga una sesión abierta y mientras el sistema esté operando a la hora programada.

Programa para programar el inicio de un proceso a una hora o fecha futura.

Programa para examinar la lista de procesos cuya ejecución fue programada con el comando at.

Programa para eliminar la ejecución de un proceso futuro programado con at.

Para que un usuario pueda programar eventos periódicos con cron, el administrador del sistema debe otorgarle permiso. Si usted tiene el permiso podrá emplear el programa crontab para agregar acciones que se ejecutaran periodicamente. Si teclea sólo crontab -e entrará al editor que tenga configurado (variable EDITOR ver Ambiente y variables de ambiente) para modificar su archivo de acciones periódicas (/var/spool/cron/crontabs/usuario), un ejemplo de tal archivo es:

Programa que permite a un usuario manejar su archivo de acciones periodicas, ese archivo reside en /var/spool/cron/crontab y es usado por el proceso cron para determinar que tareas ejecutar.


# Mi archivo de acciones periodicas para cron
PATH=/usr/bin:/usr/local/bin
0 0 24 12 *	$HOME/cron/recuerda1.sh   # Cumpleaños
0 * * * *	$HOME/cron/hora.sh

que establece la variable de ambiente PATH que se usará al realizar las acciones y especifica dos comandos por ejecutar periodicamente. El script $HOME/cron/recuerda1.sh se ejecutará el 24 de diciembre de cada año a las 00:00 (medianoche), mientras que $HOME/cron/hora.sh se ejecutara cada hora (a las 0:00, 1:00, 2:00, ... 23:00), todos los días, todos los meses, todos los años. Un archivo para crontab puede tener líneas con comentarios (iniciadas con el caracter '#'), líneas que definen variables de ambiente y líneas que especifican acciones periodicas compuestas por 6 campos y eventualmente seguidas por un comentario.

Los campos de estas acciones se separan unos de otros con uno o más espacios y son en orden: minuto, hora, dia del mes, mes, dia de la semana y comando por ejecutar. cron es un proceso que cada minuto examina los archivos crontab de los usuarios y ejecuta los comandos cuyo tiempo concuerde con la hora del sistema. El tiempo de un comando concuerda con la hora del sistema si la hora, los minutos, el mes y bien el día del mes o bien el día de la semana [6] concuerdan. La hora del sistema concuerda con la hora de una acción si ambas son iguales o sni la hora de la acción es el caracter '*', lo analogo ocurre con los minutos, meses y días.

Puede examinar su archivo de acciones periódicas bien editandolo o con crontab -l, para borrarlo puede usar crontab -r, puede remplazar sus acciones periodicas con las de un archivo (digamos microntab) con:


crontab microntab

Lecturas recomendadas: Procesos y tareas

Ejercicios: Procesos y tareas

1. Revise los procesos que están corriendo en su sistema con los programas ps, pstree, top y gtop.
2. ¿Qué hace el siguiente comando? dvi2ps -o salida.ps entrada.dvi >log 2>err &
3. Inicie un proceso que no termine en el fondo (por ejemplo cat < /dev/zero > /dev/null o yes), revise su estado empleando ps, después suspenda el proceso enviando la señal apropiada con kill, revise nuevamente el estado y compruebe que es T; reanude la ejecución enviando la señal SIGCONT; compruebe que el estado sea nuevamente en ejecución y finalmente termine el proceso enviando la señal SIGTERM.
4. Inicie un programa interactivo (que requiera interacción con el usuario, por ejemplo vi), desde bash y después de iniciado suspéndalo. Revise entonces la lista de procesos y compruebe que el nuevo proceso esté y que su estado sea suspendido. Después reinicielo y finalmente eliminelo.
5. Mida el tiempo que el siguiente programa tarda en ejecutarse: ls -R /usr/doc
6. Usando el comando at haga recordatorios de la fecha de cumpleaños de un familiar, de forma tal que el día anterior le envíe un correo recordando.
7. Algunos programas requieren mucho tiempo para ejecutarse (horas o días). Por ejemplo el siguiente programa para bc(42) que presenta los factores de un número, puede demorarse mucho tiempo para factorizar un número grande.

1. Revise los procesos que están corriendo en su sistema con los programas ps, pstree, top y gtop.

Basta teclearlos.

2. ¿Qué hace el siguiente comando? dvi2ps -o salida.ps entrada.dvi >log 2>err &

Convierte el archivo entrada.dvi a PostScript, dejando el resultado en salida.ps. La operación se realiza en segundo plano, la salida estándar es enviada al archivo log y el error estándar al archivo err

3. Inicie un proceso que no termine en el fondo (por ejemplo cat < /dev/zero > /dev/null o yes), revise su estado empleando ps, después suspenda el proceso enviando la señal apropiada con kill, revise nuevamente el estado y compruebe que es T; reanude la ejecución enviando la señal SIGCONT; compruebe que el estado sea nuevamente en ejecución y finalmente termine el proceso enviando la señal SIGTERM.


yes & 
ps -e 
kill -SIGTSTP n_p
ps -e 
kill -SIGCONT n_p 
ps -e 
kill -SIGTERM n_p

Tenga en cuenta que n_p es el número de proceso que tenga el proceso (que verá con el primer ps -e).

4. Inicie un programa interactivo (que requiera interacción con el usuario, por ejemplo vi), desde bash y después de iniciado suspéndalo. Revise entonces la lista de procesos y compruebe que el nuevo proceso esté y que su estado sea suspendido. Después reinicielo y finalmente eliminelo.

Una vez esté ejecutando vi, presione Ctrl-Z para interrumpir sesión e ir a línea de comandos. Desde la línea de comandos vea los procesos con ps, regrese entonces al proceso interrumpido con fg %-. Vuelva a interrumpir con Ctrl-Z y termine el proceso con kill %-.

5. Mida el tiempo que el siguiente programa tarda en ejecutarse: ls -R /usr/doc

time ls -R /usr/doc

6. Usando el comando at haga recordatorios de la fecha de cumpleaños de un familiar, de forma tal que el día anterior le envíe un correo recordando.

 
at 10:00 4.06.1977 << FIN1 
mail $(USERNAME)@localhost << FIN2
Acuerdese 
FIN2 
FIN1

7. Algunos programas requieren mucho tiempo para ejecutarse (horas o días). Por ejemplo el siguiente programa para bc(42) que presenta los factores de un número, puede demorarse mucho tiempo para factorizar un número grande.


     define factores(x) {
          f=2;
          maxf=x/f;
          while (f<=maxf) {
            if (x%f==0)
              { x=x/f; maxf=x/f; print f,"\n"; } else { f=f+1; }
            if (f%100000==0) { print "*"; }
         }
         return (x);
       }

Puede entrar a bc y teclear el programa presentado, después probarlo por ejemplo con factores(10) --que indica que se debe factorizar el número 10-- el cual presentará como respuesta 2 y 5. El objetivo de este ejercicio es factorizar [7] el número 129098564527119574834 empleando bc, el programa presentado y lo que ha aprendido sobre procesos en esta guía, opcionalmente también se quiere saber el tiempo que toma la factorización. Ayudas: Emplee redireccionamiento y nohup. Para salir de bc emplee quit

Crear archivo con comandos para bc (digamos factores.bc) con la definición de la función factores presentada seguida de factores(129098564527119574834) y de quit. Ejecutar:


nohup /usr/bin/time -o restime.txt bc < factores.bc > resfactor.txt & 
Que requiere 12 minutos en un Pentium MMX de 266Mhz para dar 2 12323 25849 202642820971

Notas

[1]

Dormido en este contexto se refiere a un estado al cual entra un proceso durante cierto intervalo de tiempo para dar oportunidad a otros procesos de emplear el procesador (en ps se identifica con la letra S). Un proceso está en estado bloqueado (letra D en ps) si está esperando un recurso que otro proceso está ocupando ---por ejemplo un dispositivo. El estado suspendido (letra T en ps) indica que el usuario solicitó suspender el proceso para reanudarlo después.

[2]

Puede hacerse que un programa corra en el mismo proceso del intérprete de comandos ejecutándolo con el comando exec. Con exec también puede redireccionarse descriptores de archivos del intérprete de comandos.

[3]

Primer plano: del inglés foreground

[4]

Fondo: del inglés background

[5]

make se emplea para compilar rogramas o documentos (como estás guías). En ocasiones esta labor puede tomar mucho tiempo.

[6]

En un archivo crontab los días de la semana se especifican con números de 0 a 6, 0 es domingo, 1 lunes y así sucesivamente.

[7]

El problema de factorizar un número es muy importante porque de su dificultad dependen muchos sistemas de criptografía, incluso hay premios en dinero para quienes logren factorizar ciertos números http://www.rsasecurity.com/rsalabs/challenges/factoring/numbers.html