3. Procesos y tareas

Indicadores de Logros

3.1. 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).

3.1.1. 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 [37] 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 [38], 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.

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 [39] , 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 [40] , 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.

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

3.1.2. 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.

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

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 [41] 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 &

3.1.3. 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

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 &.

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.

3.1.4. 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:

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.

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:

# 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 [42] 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

3.2. Lecturas recomendadas: Procesos y tareas

  • Los programas pstree, ps, top y gtop tiene muchas opciones que permiten configurar qué información presentar y la forma de presentarla, puede consultarlas en el manual ---la documentación de gtop puede consultarse con el sistema de ayuda de Gnome (ver Lectura Búsqueda y consulta de documentación).

  • Puede consultar más sobre señales en la página del manual sobre kill, también puede consultar la explicación detallada sobre cada señal que se presenta en el manual info de libc (Ver (info libc)).

  • Podrá encontrar información completa sobre control de tareas en la página del manual correspondiente a bash (sección Task Control).

  • Otra explicación en español, sobre procesos y control de tareas está disponible en la sección 3.11 del libro de Matt Welsh "Linux: Instalación y Primeros Pasos", traducido a español por los miembros del proyecto Lucas: http://lucas.hispalinux.es/Manuales-LuCAS/LIPP/lipp-1.1-html-2/lipp3.htm#3.11

  • La descripción del comando time que se presentó en esta sección corresponde a un comando interno de bash, puede consultar más sobre la misma en la página del manual de bash. Su sistema tiene también un programa /usr/bin/time que se emplea de forma análoga pero que puede presentar más información de los recursos empleados durante la ejecución de un programa. See (time), para más información.

  • Puede consultar más sobre at en la página del manual. La sintaxis precisa del formato de fechas y horas que at acepta, puede consultarla en /usr/doc/at/timespec.

  • El programa batch permite ejecutar un proceso cuando la carga en el sistema es baja. El programa nice inicia un proceso con una prioridad especificada por el usuario, la prioridad de un proceso que se está ejecutando puede cambiarse con el programa renice. La información completa sobre estos programas puede verla en las páginas del manual.

  • El comando trap permite asociar una secuencia de comandos a una señal, es decir que ciertos programas se ejecuten cuando bash recibe cierta señal. Por ejemplo trap "rm *.err" SIGTERM hará que el comando rm *.tmp se ejecute cuando bash reciba la señal SIGTERM. Puede consultar más sobre trap en la página del manual de bash.

3.3. Ejercicios: Procesos y tareas

3.3.1.

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

3.3.2.

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

3.3.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.

3.3.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.

3.3.5.

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

3.3.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.

3.3.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 [43] 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



[37] 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.

[38] 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.

[39] Primer plano: del inglés foreground

[40] Fondo: del inglés background

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

[42] 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.

[43] 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