Control
de Señales
Cuando una señal se envía a
un proceso, que no esté preparado para recibirla, el proceso se mata.
SIGNAL(señal,
&funcion)
int señal;
int
(*función)(); función a realizar cuando se recibe una señal.
Esta llamada se utiliza para
indicar que se está preparado para recibir algún tipo de señal y suministrar la
dirección del procedimiento manejador de la señal.
Después del SIGNAL, si se
recibe una señal por ejemplo SIGINT (pulsar la tecla DEL), se efectúa:
1)
El estado del proceso se guarda en su propia pila.
2)
Se ejecuta el manejador de la señal.
SIGRETURN
(&contexto)
Es llamado por el manejador
que atiende la señal cuando termina. Recupera el estado del proceso
interrumpido desde la pila y lo continúa.
Los tipos de señales son:
1.
SIGHUP El modem ha detectado línea telefónica
colgada
2.
SIGINT Interrupción de teclado, la tecla DEL ha
sido pulsada
3.
SIGQUIT Señal Quit (desde el teclado CTRL \)
4.
SIGILL Instrucción ilegal
5.
SIGTRAP Traza de los traps (excepciones)
6.
SIGABRT Abortar un programa
7.
SIGBUS Error en el Bus
8.
SIGFPE Excepción por rebosamiento de coma flotante
9.
SIGKILL Matar un proceso
10.
SIGUSR1 El usuario define la señal # 1
11.
SIGSEGV Violación de segmentación
12.
SIGUSR2 El usuario define la señal # 2
13.
SIGPIPE Escritura en pipe sin lectores
14.
SIGALRM Alarma
15.
SIGTERM Software genera una señal de terminación
16.
SIGSTKFLT Fallo en el stack
17.
SIGCHLD Cambia el estado del hijo, terminado o
bloqueado
18.
SIGCONT Si está bloqueado continuar
19.
SIGSTOP Señal de paro
20.
SIGTSTP Paro del teclado
21.
SIGTTIN Proceso en segundo plano quiere leer,
lectura terminal
22.
SIGTTOU Proceso en segundo plano quiere escribir,
escritura terminal
23.
SIGURG Condición urgente
24.
SIGXCPU Excedido el límite de la CPU
25.
SIGXFSZ Excedido el limite del tamaño de un fichero
26.
SIGVTALRM Alarma del reloj virtual
27.
SIGPROF Historial del reloj
28.
SIGWINCH Cambia el tamaño de la ventana
29.
SIGIO Ahora es posible la entrada salida
30.
SIGPWR Fallo en la alimentación
31.
SIGSYS Llamada al sistema erronea
32.
SIGRTMIN Primera señal en tiempo real
33.
SIGRTMAX Última señal en tiempo real
Después de recibir una
señal, en principio es necesario volver a permitir recibir otra señal con otro
SIGNAL, ya que si no, puede recibirse una señal y matar el proceso (acción por
defecto), existe un parámetro para que se vuelva a cargar la función.
Existen dos funciones
predefinidas que el usuario puede utilizar:
· SIG_IGN, para
que las señales se ignoren (excepto SIGKILL).
· SIG_DFL, para
ejecutar la acción por defecto de matar al proceso.
Ejemplo: Supongamos que
lanzamos un comando en modo tanda: command &
Es indeseable que la señal
DEL, del teclado pueda afectar a ese proceso, así, el Shell después de ejecutar
el FORK, pero antes del EXEC deberá hacer
· signal (SIGNIT,
SIG_IGN);
· signal (SIGQUIT,
SIG_IGN);
Que inhiben las señales
DEL, y QUIT (CTRL\).
SIGACTION
(sig, *act, *oact)
Es una nueva versión de
signal, examina, pone o modifica los atributos de una señal.
Sig es un entero
que indica la señal.
*act es una
estructura que contiene los atributos y manejador de la señal
*oact es la
estructura que recibe los atributos antes de la llamada.
ALARM
(segundos)
Esta llamada se utiliza
para interrumpir un proceso al cabo de un cierto tiempo, su parámetro
especifica el tiempo en segundos, después del cual el núcleo envía la señal
SIGALRM al proceso.
Un proceso solo puede tener
una alarma pendiente, para resetear una alarma, basta hacer una llamada de
alarma con parámetro cero.
PAUSE
(segundos)
Esta llamada le dice al
S.O. que suspenda al proceso, hasta que se reciba una señal.
SIGPROCMASK(how,
&set, &old)
Esta señal permite bloquear
un conjunto de señales mediante una mascara de bits que le envía al núcleo del
sistema.
SIGPENDING(SET)
Obtiene el conjunto de
señales bloqueadas.
SIGSUSPEND(sigmask)
Permite a un proceso
establecer atómicamente el mapa de bits de las señales bloqueadas y suspenderse
a sí mismo.
Control
de Procesos
En este tópico parece no
haber mucho que decir; existe una serie de herramientas para administrar los
procesos, algunas de las cuales se valen de señales para cumplir con su objetivo.
Algunos de estos procesos
son:
pid = fork() - crea un
proceso hijo idéntico al proceso padre.
pid = waitpid(pid,
&statloc, opts) - espera a que un hijo determinado termine y coge su
condición de salida.
s = wait(&status) -
espera a que un proceso hijo termine y coge su condición de salida devuelve el
pid del hijo que termina, llamada antigua.
s = execve (name, argv,
envp) - sustituye la imagen en memoria de un proceso.
exit(status) - pone fin a
la ejecución del proceso y devuelve la
condición de salida.
size = brk (addr) - fija el
tamaño del segmento de datos a (addr).
pid = getpid() - devuelve
el id del proceso solicitante.
pid = getpgrp() - devuelve
el id de grupo de procesos del proceso solicitante.
pid = setsid() - crea una
nueva sesión y asigna el pid del invocador como identificador del grupo de
procesos.
s = ptrace(req, pid, addr,
data) - controla un proceso para depurar.
FORK()
Crea un nuevo proceso,
exactamente igual al proceso original, incluyendo los descriptores de
ficheros, registros, ambiente, etc.
La llamada FORK devuelve un
valor después de ejecutarse, este valor
es:
cero -> en el proceso hijo
pid (identificador del
proceso hijo -> en el padre
Mediante este valor los
procesos pueden saber cuál es el padre y
cuál es el hijo.
WAITPID
pid = waitpid(pid, &statloc, opts) - espera a
que un hijo determinado termine, devolviendo el pid del proceso que termina, y
coge su condición de salida.
En mucho casos, el hijo
creado por el FORK necesita lanzar un
proceso, distinto al del padre. Ejemplo:
El Shell, lee un comando,
lanza un proceso hijo, y debe esperar hasta que el proceso hijo ejecute el comando, posteriormente lee un nuevo comando cuando el hijo termina.
Para esperar a que el hijo
termine, el padre debe ejecutar WAITPID.
Si el parámetro pid vale
-1, el padre espera por el primer hijo que termina El segundo parámetro statloc
es la dirección de una variable (estado
de salida) que es escrita por el proceso hijo para indicar terminación normal o anormal.
EXEC.
s = execve (name, argv,
envp) - sustituye la imagen en memoria de un proceso.
name - nombre del fichero
que contiene el programa a ejecutar.
argv - vector de
argumentos.
envp - vector
ambiente
En el caso del Shell, el
proceso hijo debe ejecutar el comando, esto lo hace mediante la llamada EXEC,
la cual hace que la imagen del hijo, sea reemplazada por el fichero que hay en
el primer parámetro de EXEC.
Ejemplo: Shell simplificado
con FORK, WAITPID y EXEC.
While (TRUE){ /*
bucle indefinido */
read_command (command, parámetro); /*
lee comando */
if ( fork() != 0){ /* lanza un proceso
hijo */
waitpid(-1,&status,0); /* el
padre espera a que hijo acabe */
}else{
execve(command, parámetros, 0);
/* ejecuta el comando */
}
};
EXIT().
Esta llamada la deben
utilizar lo procesos cuando terminan.
Devuelve al padre un valor
de estatus (0 a 255), que se carga en el byte menos significativo de la
variable estatus de WAITPID, un cero es terminación normal, otro valor es
error.
BRK(adr)
Esta llamada cambia el
tamaño del segmento de datos de un programa. El parámetro adr que indica el
nuevo tamaño en bytes del segmento de datos. Devuelve el tamaño actual del
segmento de datos.
La rutina sbrk, en la
librería, también cambia el tamaño del segmento de datos, su parámetro indica
el número de bytes que aumenta (positivo) o disminuye (negativo) el segmento de
datos.
GETPID
Devuelve el identificador
del proceso (pid) que lo ejecuta. En un Fork, al padre se le devuelve el pid
del hijo, mientras que al hijo se le devuelve un cero, si el hijo quiere saber
su pid, deberá efectuar un GETPID.
0 comentarios:
Publicar un comentario