You are on page 1of 51

Tema 8: Procesos en Linux

IES Serra Perenxisa 2009


Gestión de Procesos

Un programa ejecutable es leído del disco por el kernel
y es cargado en memoria para ejecutarse,
convirtiéndose en un proceso.

En un proceso no sólo hay una copia del programa,
sino además el kernel le añade información adicional
para poder manejarlo.

Un proceso se compone de tres bloques
fundamentales:
 segmento de texto
 segmento de datos
 pila
Espacio de Direcciones de un Proceso Unix

0xFFFFFFFF
kernel system segment
(call system)
kernel stack
stack $fp
(dynamic allocated mem)
$sp

shared libraries

address space heap


(dynamically allocated mem)
un-initiated data (bss)
static data
read/write initiated data (data segment)
only read initiated data
code
$pc
0x0 (text segment)
Gestión de Procesos
 Segmento de texto: código de programa
 Segmento de datos: variables globales y estáticas
 Pila

Lo crea el kernel y su tamaño es gestionado
dinámicamente por el.

Es una secuencia de bloques lógicos o stack frames

Un stack frame se introduce o saca en función de si
se llama o se vuelve de la llamada a una función.
 Stack frame se compone de:
 Las variables locales de función
 Parámetros de función
 Info. para volver al estado anterior de la llamada
Gestión de Procesos
 Info. para volver al estado anterior de la llamada.

contador de programa

puntero a pila al stack frame anterior

Los procesos pueden ejecutarse en dos modos: usuario
y kernel.

Cada modo maneja su propia pila o stack
 stack del kernel: contiene los stack frames de las
llamadas a sistema(funciones que se ejecutan en modo
kernel)
 stack del usuario: stack frames de funciones que se
ejecutan en modo usuario
Gestión de Procesos

UNIX/Linux es un sistema multiproceso que permite la
ejecución de varios procesos de forma simultánea

Requiere de otro programa llamado “Planificador o
scheduler” que permite gestionar que proceso entra a
ejecutarse en cada instante en la CPU, ya que esta es un
recurso limitado.

Todo proceso nace cuando algún otro proceso ejecuta la
llamada al sistema clone. Una de las muchas formas de
llamar a clone es a través de la función fork.

clone crea un duplicado idéntico del proceso que la ha
llamado.
API de Unix para manejo de Procesos
 Unix proporciona un número de llamadas al sistema para creación y control de
procesos, que incluye:
 fork: usado para crear un nuevo proceso (hijo).
 exec: utilizado para cambiar el proceso actual por otro.
 vfork: usado para crear un proceso nuevo, que comparte el espacio de
direcciones del padre.
 clone(): llamada al sistema en Linux y es una forma genérica de fork() y
pthread_create().
 wait: esperar por el término de la ejecución de algún proceso hijo.
 waitpid: usado para esperar el término de ejecución de un proceso hijo
específico.
 sleep: suspende la ejecución de un proceso por un tiempo determinado.
 kill: usado para matar un proceso o enviar una señal.
 abort: usado para terminar con la ejecución de un proceso en forma anormal.
 getpid: devuelve el pid del proceso.
 getppid: devuelve el pid del proceso padre.
 getuid: devuelve el identificador de usuario.
 getpgrp: devuelve el identificador de grupo del proceso.
Gestión de Procesos:clone

Nuestro nuevo proceso no verá el espacio de direcciones
del proceso padre, ni viceversa.

Con mucha frecuencia, después del clone el proceso llama
a exec para lanzar un programa nuevo.

La llamada a exec carga un programa en el espacio de
direcciones del proceso y le pasa el control, perdiéndose el
proceso llamante.

Si un proceso quiere lanzar un programa sin desaparecer, lo
que hace es llamar a clone y que el hijo llame a exec
(servicios).
Gestión de Procesos:fork

Fork: Crea un proceso hijo. Devuelve 0 al proceso hijo y
el PID del hijo al proceso padre. El proceso hijo creado
es una copia exacta del padre, excepto que recibe un
valor diferente de la llamada fork. Devuelve un valor -1
en caso de no poder crearse el proceso hijo.
ret=fork()
if (ret==-1) {printf(“ERROR”);}
else if (ret==0) {printf(“HIJO”);}
else printf(“PADRE”)
Gestión de Procesos:fork

Todos los procesos tienen un único padre, pero un
padre puede tener múltiples hijos.

Existe un proceso especial cuyo PID es 0, este se crea
al arrancar el sistema y después de hacer una llamada
fork se convierte en el proceso intercambiador
(swapper), el proceso hijo se llama init y su PID vale 1.
Este se encarga de arrancar los demás procesos que
requiere el sistema.
Usando fork() crear (duplicar) un proceso
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h> e o
qu ces
ig o ro
void main(void) ó d el p
{ C ta re
u
c pa d
pid_t pid;
Ej e
int i;
int n = 10;

for (i = 0; i < n; i++) {


pid = fork();
if ( pid != 0 ) {
printf("\n\n*********************** ITERACION %d **************\n",i);
printf("Recien creado: %d\n",pid);
printf("Creado por: %d\n",getpid());
printf("*****************************************\n");
break; Código que ejecuta
} el proceso hijo
}

printf("\n\n-------------------------FINAL DEL BUCLE -------------------------\n");


printf("Finalizando bucle de: %d\n",getpid());
printf("....padre = %d\n", getppid());
}
Gestión de Procesos:PID

Cuando un proceso muere libera su pid y se puede
asignar a cualquier nuevo proceso.

En Linux 2.6 el PID se almacena en un entero y permite
teoricamente hasta 2147483647(int 32bits=2^(31) +bit
signo) procesos.
cat /proc/sys/kernel/pid_max ->32768 (por defecto)
echo 10000001 > /proc/sys/kernel/pid_max (hasta 1
Millón)

Con frecuencia se llega antes a la limitación de cota de
descriptores, ya que cada proceso consume al menos 3
descriptores (ES, SS, SE)
cat /proc/sys/fs/file-max ->101815(por defecto)
Gestión de Procesos:estados

El tiempo de vida de un proceso se puede dividir en un
conjunto de estados.

En un sistema monoprocesador un proceso no esta
continuamente ejecutándose, su estado irá cambiando
según unas reglas bién definidas.

En el siguiente gráfico veremos cual es la transición de
procesos en UNIX/Linux y procederemos a su
explicación:
Gestión de Procesos:estados
1.-Ejecutándose en modo usuario: tiene el control del
procesador mientras dura el quanto o no realice una llamada al
sistema.
2.-Ejecutándose en modo kernel: Cuando el proceso realiza
una llamada a sistema, el proceso cambia de estado y pasa
ejecutar código de área de kernel. Cuando termina:
 Termina la tarea interrupción (iret) vuelve a la siguiente
instrucción que la llamó.
 Si termina el quanto se hace un cambio de contexto,
pasando el siguiente proceso a modo usuario
 Si carece de algún recurso->Estado dormido
 Si termina con exit->Estado zombi
Gestión de Procesos:estados
3.-Planificado en memoria: tiene reservado los recursos de
sistema que necesita. El proceso no se esta ejecutando, esta
en cola de "listo para ejecutarse" esperando a que el
planificador de tareas(scheduler) se lo permita.
4.-Dormido en memoria: El proceso esta durmiendo cargado en
memoria, ya que esta esperando que se complete una
operación (E/S,tiempo de espera(timer)(ejm:sleep 10),espera
de recibir un evento o mensaje)
Nota: No puede haber un proceso, ejecutándose en modo
usuario y kernel a la vez.
Gestión de Procesos:estados
5.-Planificado en swap: Esta en memoria secundaria,listo para
ejecutarse, pero el intercambiador (proceso 0 ó swapper) debe
cargar el proceso en memoria antes de que el
planificador(scheduler) pueda ordenar que pase a ejecutarse.
6.-Dormido en swap: El proceso esta durmiendo y el
intercambiador ha descargado el proceso hacia una memoria
secundaria para dejar espacio en la memoria principal donde
poder cargar otros procesos.
7.-El proceso esta volviendo del modo superusuario al modo
usuario, pero el planificador se apropia del proceso y hace un
cambio de contexto, pasando otro proceso a ejecutarse en
modo usuario.
Gestión de Procesos:estados
8.-El proceso acaba de ser creado(con fork) y está en un
estado de transición; el proceso existe, pero ni está preparado
para ejecutarse, ni durmiendo. Este estado es el inicial para
todos los procesos, excepto el proceso 0.
9.-El proceso ejecuta la llamada exit y pasa al estado zombi. El
proceso libera todos los recursos pero mantiene la entrada en
la Tabla de Procesos. No termina de morir, esperando la
notificación por parte del padre, de que ha recogido el registro
que contiene el código de salida y su estado. Es un estado
temporal. En caso de que el proceso padre muera antes de que
finalice el hijo, será el proceso init quién asuma su paternidad.
Gestión de Procesos: estados
1- Para ver un proceso en ejecución, bastaría con ejecutar ps –aux y
localizar en la salida del comando el proceso “ps”, que debería estar en
ejecución.

2- Si compilamos “running.c” con la orden “gcc –o running running.c” y


ejecutamos el programa “./running” también veremos un proceso en
ejecución continuada.

3-Con el programa “waiting.c” que tiene un getchar(), el programa


simplemente espera una entrada y está Sleeping. Si se le intenta enviar a
segundo plano “./waiting &” el sistema nos informa que el proceso pasa a
estado “T” (stopped) por que en segundo plano no puede recibir nada por
stdin.
Gestión de Procesos: estados
4-”ej_fork.c” : El padre trabaja mientras que el hijo acaba.

Esto resulta en: Padre con estado “R” e hijo con estado “Z” <defunct>

Si hiciésemos un CTRL+Z el padre pasaría a estar T (stopped).

Si hacemos kill -9 padre, el hijo muere también


Gestión de Procesos: ciclo de vida
La vida de un proceso comienza con la llamada al sistema
de fork, desde el shell por ejemplo con ./a.out :
1.-Con la llamada a fork se crea el proceso, iniciándose la
información de contexto y asignando un PID al proceso hijo
a.out. Su proceso padre será el "shell".( Un proceso no se
crea si: no puede encontrar el programa, falta de memoria, se
ha sobrepasado el número de procesos que se puede crear...)
2.-El proceso pasa a estado "listo para ejecutarse".
Gestión de Procesos: ciclo de vida
3.-Existe una función "scheduler" o "planificador" que en
función de la política , se encarga de seleccionar a un
proceso de la lista de "listo para ejecutarse".
4.-Un vez seleccionado el proceso a ejecutarse por el
"planificador", se llama a la función "dispatcher" que se
encarga de pasar a estado de ejecución a dicho proceso,
restaurando su información de contexto.
Gestión de Procesos:
ciclo de vida
5.-En ejecución se pasa de modo usuario a modo
supervisor a través de una llamada a sistema o interrupción
(cada vez que se necesita ejecutar alguna rutina del sistema
operativo tal como una operación de E/S para escribir un
mensaje en pantalla...). En modo usuario, se verifica la zona
de memoria a la que se accede, no sobrepase su área de
programa de usuario (zona datos e instrucciones) y no
modifica el área del Sistema Operativo(virus). Una vez
finalizada la ejecución de la rutina de E/S, el S.O devuelve el
control al programa de usuario, pasando a modo usuario.
printf(“ejemplo”) (modo ususario)->llamada a sistema
write(modo kernel)
Gestión de Procesos:
ciclo de vida
6.-En caso de espera de un proceso por alguna operación de
E/S , por un evento de otro proceso, o un timer(intervalo de
tiempo), el planificador envía al proceso a “estado
durmiendo”. Para lo cual el planificador selecciona el siguiente
proceso a ejecutar y el dispatcher lo pasa a estado de
ejecución. Una vez que la razón por el que un proceso esta
"durmiendo" finalice el planificador pasa a estado "listo de
ejecución".
7.-Los procesos tienen un quanto de tiempo de ejecución para
el uso equitativo de la CPU. Sabiendo que los procesos más
prioritarios tendrán mayor número de quantos.
Gestión de Procesos:
ciclo de vida
8.-En caso de que la memoria esté saturada y haya
necesidad de cargar un programa más prioritario en memoria,
el swapper o intercambiador se encarda de pasar un
proceso menos prioritario a memoria secundaria guardando
la información necesaria para volverlo a cargar en memoria, y
una vez finalizado la ejecución de un proceso, de pasarlo a
memoria. Este transiego de memoria a disco y disco a memoria
se le denomina "swapping de procesos".
9.-Un proceso puede acabar su ejecución si :
 llamada al sistema de fin_programa: exit
 Otro proceso le manda un SEÑAL de SIGKILL: kill -9 nºPID
Gestión de Procesos:
ciclo de vida

En ambos casos pasa a estado zombi. El proceso ya no
existe pero deja para su proceso padre un registro (código de
salida y algunos datos estadíticos tales como tiempo de
ejecución)

Para que un proceso pueda matar a otro es necesario que
tenga privilegios, un proceso padre puede matar a sus
procesos hijos.
Gestión de Procesos:
ciclo de vida

Los procesos se comunican habitualmente realizando
llamadas a sistema de "esperar_hijo", que permite al proceso
padre sincronizarse con la finalización de sus hijos y obtener la
información de cómo han acabado los hijos por medio de algún
tipo de código de retorno.
ret=fork()
if (ret==-1) {printf(“ERROR”);}
else if (ret==0) {printf(“HIJO”);}
else {wait(&estado);printf(“PADRE”)}
Gestión de Procesos:
Tabla de Procesos

El sistema operativo mantiene una tabla de
procesos, dentro de la cual se almacena un Bloque de
Control de Proceso o PCB (Process Control Block).
Un PCB tiene los siguientes campos:
 Información de identificación:

PID(Process IDentifier) y PPID(Parent
Process Identifier) para relaciones padre-hijo.

UID (User Identifier) y GID (Group Identifier)
:determina los privilegios del proceso
Gestión de Procesos: Tabla de
Procesos
 Información de control para gestionar el proceso:

Planificación y estado:
 Estado:

TASK_RUNNING(ejecutándose o preparado)

TASK_INTERRUPTIBLE(dormido, pero admite
cualquier señal)

TASK_UNINTERRUPTIBLE ( dormido, pero
sólo responde a la señal que espera)

TASK_STOPPED( stopped o traced)

TASK_ZOMBIE(esperando un wait() )
 Evento por el que espera si esta bloqueado
Gestión de Procesos: Tabla de
Procesos
 Información de control para gestionar el proceso:

Planificación y estado:
 Temporizadores que contabilizan el tiempo de
CPU utilizado en modo kernel y modo usuario

Descripción de los segmentos de memoria asignados
al proceso.

Estado del procesador: valor de los registros de la cpu
Gestión de Procesos: Tabla de
Procesos
 Punteros para estructurar los procesos en colas. Para que
el planificador las gestione.
 Comunicación entre procesos:

Descriptores de eventos: Qué eventos despertarán al
proceso.

Campo de señales: enumera las señales recibidas
pero todavía no tratadas.
Gestión de Procesos: Cambio de
Contexto

Cuando se esta ejecutando un proceso, se dice que el sistema
se esta ejecutándo en el contexto de un proceso.

Se denomina cambio de contexto a la acción de cargar el
procesador con el contexto del proceso que pasa a ocupar
la CPU, salvando previamente el contexto del proceso que
abandona la CPU en su PCB.
Gestión de Procesos: Cambio de
Contexto

Se provoca un cambio de contexto cuando:
 fin quanto
 finaliza el proceso
 operación de sincronización-tenga que esperar
 llamada al sistema (operación de entrada/salida) mediante
el mecanismo trap (interrupción software) queda bloqueado
a la espera de finalizar la operación.
 interrupción hardware que desbloquee un proceso más
prioritario.
 la llegada de un proceso más prioritario
Gestión de Procesos: Planificador de
Procesos:Unix,tradicional

Los PCBs estarán ordenados en la colas de preparados de
acuerdo a la política de planificación utilizada.

El planificador se encarga de decidir a quién dará la tajada
(slice o quanto) de tiempo.

En Unix se utiliza el algoritmo de planificación que se
denomina Round Robin Multinivel con Prioridades
Dinámicas.
Gestión de Procesos: Planificador de
Procesos:Unix,tradicional

1º aproximación: Algoritmo Round-Robin
 Cola FIFO de procesos planificados
 Funcionamiento: Se coge el proceso más antiguo y una vez
ejecutado su quanto, vuelve a introducirse en la cola.
 Ventaja: Es un algoritmo justo.
 Desventaja: los procesos con mayor prioridad se ejecutarán
con la misma frecuencia que los menos prioritarios
Gestión de Procesos: Planificador de
Procesos:Unix,tradicional

2º aproximación: Algoritmo Round-Robin Multinivel
 Diferentes colas FIFO, cada una para procesos de la misma
prioridad.
 Funcionamiento: Se coge el proceso más antiguo de la cola
de mayor prioridad. Sólo si la cola de mayor prioridad esta
vacía pasamos a la de siguiente menor prioridad.
 Ventaja: Óptimo para sistemas de tiempo real
 Desventaja: No justo, puede haber procesos que jamás se
ejecuten.
Gestión de Procesos: Planificador: Unix
tradicional

3º aproximación: Algoritmo Round-Robin Multinivel con
Prioridades Dinámicas
 Diferentes colas FIFO, cada una para procesos de la misma
prioridad. La prioridad tiene un componente estático(nice de 19
a -20) y otro dinámico (según el proceso va ejecutando slices,
su prioridad dinámica va cayendo, y si no emplea el
procesador su prioridad dinámica sube).
 Funcionamiento: Por cada segundo de tiempo se recalculan
las prioridades y se reajustan las colas. Se coge el proceso
más antiguo de la cola de mayor prioridad. Sólo si la cola de
mayor prioridad esta vacía pasamos a la siguiente menor
prioridad.
 Ventaja: Es justo
 Desventaja: El tiempo recalculando las prioridades dinámicas
Gestión de Procesos:
Planificador:Unix,tradicional

3º aproximación: Algoritmo Round-Robin Multinivel con
Prioridades Dinámicas
 Los procesos tienen prioridades.
 Existe una cola para cada una de la prioridades.
 Se atiende primero a los procesos de la cola -32, en caso de
estar vacía se pasa al siguiente nivel hasta llegar a 31.
 En caso de no haber procesos planificados, se ejecuta el
proceso idle
 Prioridad Total=Prioridad Base + (uso de cpu/2) + Valor
Nice
 Prioridad Total se calcula cada segundo
 La Prioridad Base será un valor negativo, si proceso se
ejecuta en modo kernel y positivo si modo usuario, y depende
de la prioridad del padre.
Gestión de Procesos:
Planificador:Unix,tradicional

3º aproximación: Algoritmo Round-Robin Multinivel con
Prioridades Dinámicas.
 El Valor Nice:

Es un valor comprendido entre -20 a 19. Por defecto es 0.

Un usuario normal únicamente puede bajar la prioridad de
su proceso ejecutándolo:
nice -n 19 yes>/dev/null &
[1] 2546

Un superusuario puede aumantar/reducir la prioridad de un
proceso:
 Cuando va a ejecutar 1º vez: nice -n -20 yes>/dev/null &
 Una vez en ejecución: renice -20 2546
Ordenes relativas a procesos: ps

Lista los procesos activos en el sistema

Examinar las opciones en el manual (castellano):
 a: información de los procesos de todos los usuarios
 e: variables de entorno
 u: muestra los procesos de un solo usuario
 r: sólo procesos en ejecución
 x: todos los procesos del sistema
 l: salida larga

Ejemplos: ps –aux, ps -edaf
Ordenes relativas a procesos: ps

Campos de salida:
 UID (id. de usuario), PID (id. de proceso), PPID (padre),
 %CPU (índice de uso del procesador),
 START (hora de inicio),
 TTY (terminal en la que se ejecuta el proceso),
 TIME (tiempo acumulado de CPU consumido por el proceso)
 PRI (prioridad de ejecución, dinámica, a menor nº mayor prioridad)
 NI(Valor del NICE)
 SIZE (tamaño en bloques)
 RSS (tamaño en Kb del programa en memoria)
 STAT (Estado del proceso):

D:Durmiendo ininterrumpiblemente

R:En ejecución en ese momento

S:Durmiendo

Z:Zombie

T:Parado

W: Swapped out (sin páginas residentes)

N:Nice positivo
Ordenes relativas a procesos: ps/top

gcc –o running running.c

cp running running1 (dos copias del ejecutable)

./running & + ./running1&

jobs

ps –edaf

Top

S (intervalo) : 0.5 / 1

R (renice) -20 running (máxima prioridad)

R (renice) -5 running1

K (kill)

U (user)

Al hacer el renice el proceso con el número más negativo, consume más CPU y
su tiempo de ejecución crece.

Los dos procesos colapsan el 99% de uso de la CPU. El ratón va lento.
Ordenes de procesos: nice & renice

Nice –n comando : fija el valor de nice para la ejecución de un cierto proceso

Valores válidos de -20 a 19

Los usuarios sólo pueden bajar la prioridad

El root puede subir la prioridad a un proceso.

Ejemplo: lanzar los dos running y running1 con nice diferente y con el
comando top visualizar lo que ocurre.


Renice –n PID: Modifica la prioridad a un proceso ya en ejecución

Ejemplo: invertir la ejecución de running y running1, para que el menos
prioritario pase a ser más prioritario (y consuma más CPU).
Ordenes de procesos: sleep, wait, nohup

Sleep tiempo (segundos): Demora durante un cierto tiempo el inicio de una
orden o genera una espera durante la ejecución

(sleep 3600; who >> registro) &


Wait: cuando en programación shell, nos interesa esperar a que acaben los
procesos en background (&) antes de ejecutar la siguiente orden:

Orden1 > archivo1 &

Orden2 > archivo2 &

Wait

Sort archivo1 archivo2


Nohup: Cuando un proceso muere, todos sus subordinados –si los hubiera-
mueren también. Al finalizar una sesión (login, konsole) también.

Con nohup, un comando seguirá en ejecución a pesar de que el usuario que lo
lanza se haya desconectado. Es interesante redirigir las salidas para capturarlas:
 Nohup orden > salida 2>errores &
Ordenes de procesos: kill y señales

Kill: envía señales a procesos
 Kill –nº_de_señal PID
 Un usuario puede eliminar cualquier proceso suyo
 El root puede eliminar cualquier proceso
 Las señales son sucesos externos a los procesos que tienen un número asociado.
 Por defecto se ejecuta la señal 15 SIGTERM (finalización software)
 La señal nº 9 SIGKILL provoca la terminación incondicional e inmediata del
proceso

Kill -9 PID

 Ejemplo: Desde konsole arrancar varios programas y finalizarlos con kill y/o con
xkill.
Ordenes de procesos: señales
 Las señales son mecanismos de comunicación asíncrona de procesos
(interrupciones software que pueden ser enviadas a un proceso para informarle de
alguna situación especial)
 Permiten al proceso reaccionar a los eventos provocados por ellos mismos o por
otros procesos. Puede generarse de diversas maneras:

Excepción Hardware (acceso a página de memoria no asignada= SIGSEGV)

CTRL+C (SIGINT) del usuario

Llamada a kill (envía esa señal a un proceso)

Evento gestionado por el núcleo)
 Cuando un proceso recibe una señal hay 3 acciones predeterminadas:

Ignorar la señal

Invocar una rutina de tratamiento standard (por lo general provocan la terminación del
proceso y generan un core)

Invocar una rutina propia (modificada por el proceso)
Procesos: señales de terminación de
procesos
Núm. Nombre Descripción
1 SIGHUP Terminación del proceso, desconexión

2 SIGINT CTRL+C por teclado


3 SIGQUIT Terminación con core
6 SIGABRT Terminación anormal
9 SIGKILL Terminación no evitable
15 SIGTERM Terminación emitida por kill
Procesos: señales de excepción
hardware
Núm. Nombre Descripción
4 SIGILL Instrucción ilegal

5 SIGTRAP Punto de parada en programa


8 SIGFPE Floating Point Exception
11 SIGSEGV Dirección de memoria no válida
Procesos: señales de suspensión o
seguimiento en la ejecución de procesos

Núm. Nombre Descripción


17 SIGCHLD Terminación de un hijo

18 SIGCONT El proceso se lleva a primer o segundo plano


19 SIGSTOP Suspensión de proceso
20 SIGTSTP Emisión de CTRL+Z
Procesos: señales de gestión de
alarmas, SAI, entradas/salidas
Núm. Nombre Descripción
24 SIGXCPU Límite de CPU (tiempo) sobrepasado

2 SIGALRM Fin del tiempo de un timer


SIGPWR Fallo de alimentación
23 SIGURG Datos urgentes para los sockets
Procesos: Control de trabajos (bg, fg,
jobs, CTRL+Z)
1-Desde un terminal en X lanzamos un proceso (mozilla)
2-El terminal queda bloqueado
3-Con CTRL+Z paramos el proceso
4-Con ps vemos que el proceso esta sTopped
5-Con “jobs” vemos la lista de tareas de esa terminal
6-Con bg lo mandamos a segundo plano
7-Con fg + nº de trabajo lo traemos a primer plano de nuevo (bloqueamos terminal)

You might also like