Actualizado el 26 de Octubre del 2020 (Publicado el 23 de Febrero del 2018)
761 visualizaciones desde el 23 de Febrero del 2018
253,7 KB
19 paginas
Creado hace 18a (28/11/2006)
Tema 4 : señales
Sistemas Operativos:
Programación de Sistemas
Oscar Déniz Suárez
Alexis Quesada Arencibia
Francisco J. Santana Pérez
Curso 2006-07
eventos a los procesos
procesa inmediatamente.
Señales
Las señales son un mecanismo para comunicar
Cuando un proceso recibe una señal, la
Cuando un proceso recibe una señal puede:
Ignorar a la señal, cuando es inmune a la misma
Invocar la rutina de tratamiento por defecto
Invocar a una rutina de tratamiento propia
Señales
Señales
SIGTERM = Finalización controlada. Se envía para
Algunas señales importantes <signal.h>:
indicarle a un proceso que debe acabar su
ejecución. Puede ser ignorada. Definiremos una
rutina para definir el comportamiento del sistema si
recibe esta señal.
SIGKILL = Finalización abrupta. No se puede ignorar
SIGINT = Interrupción. Se envía cuando se pulsa la
SIGCLD = Terminación de algún proceso hijo. Se
OTRAS: SIGTRAP, SIGIOT, SIGEMT, SIGFPE,
tecla de interrupción (Ctrl+C). Por defecto, se
interrumpe el programa.
envía al proceso padre. Ignorada por defecto
SIGBUS, SIGSEGV, SIGSYS, SIGPIPE, SIGALRM,
SIGPWR…
Señales
Señales disponibles para el programador:
#include <string.h>
#include <signal.h>
char *strsignal(int sig);
SIGUSR1 y SIGUSR2. Son señales reservadas para el uso
del programador. Ninguna aplicación estándar va a usarla y su significado
es el que quiera definir el programador en su aplicación. Por defecto
tienen la acción de terminar el proceso.
Para ver una cadena de texto sobre una señal:
Envío de señales
Para enviar una señal a un proceso o grupo de
procesos:
#include <signal.h>
int kill(pid_t pid, int sig);
int killpg(int pgrp, int sig);
Si pid > 0, es el PID del proceso al
que enviamos la señal
Si pid = 0, la señal es enviada a todos
procesos del grupo
Si pid = -1, la señal es enviada a los
procesos cuyo id. Real es igual al id.
Efectivo del proceso que la envía.
Para enviar una señal a sí mismo:
#include <signal.h>
int raise(int sig);
Envío de señales
Ejercicio Práctico:
vamos a crear un programa que cree un
proceso hijo, en el que el hijo estará siempre
haciendo printf de (“soy el hijo con pid = “,
pid), y a continuación un sleep(1).
El padre, una vez creado el hijo, esperará 10
tiempos (sleep(10)) y luego mandará una
señal al hijo de terminación y luego
terminará.
Tratamiento
de señales
#include <signal.h>
void (*signal (int sig, void (*action) ())) ();
action puede ser:
Para especificar qué tratamiento debe
realizar un proceso al recibir una señal.
Sig será el valor de la señal, y *action es
la acción que se tomará al recibir la señal
y puede tomar tres clases de valores:
general, es la de abortar e incluso dar core.
SIG_DFL = acción del manejador por defecto. Por lo
SIG_IGN = la señal se debe ignorar
Dirección a la rutina de tratamiento
Tratamiento de señales
Ejemplo práctico:
Vamos a crear un programa que intercepte la señal
generada al pulsar las teclas ctrl-C.
Para ello, programamos la función que va a manejar
la interrupción, y hacemos un printf de “esperando a
ctrl-c”.
Ver error de primera ejecución y por qué. Podemos
solventarlo??????
No es el caso de SIGILL, SIGTRAP y SIGPWR,
pues no hay tratamientos por defecto a estas rutinas.
Espera
#include <unistd.h>
int pause(void);
pause deja al proceso suspendido en espera
por una señal (cualquiera)
Pause devuelve un -1 cuando le llega la interrupción
y pone errno a EINTR
Espera
Ejercicio práctico:
mediante:
kill -s USR1 pid
consola.
Vamos a utilizar SIGUSR1 para que un programa
genere un número aleatorio cada vez que reciba
dicha señal. Usaremos SIGINT para inhabilitar la
señal mientras se atiende la interrupción.
La señal la daremos desde la consola del sistema
Para finalizar, enviaremos un SIGTERM desde
Espera (II)
Para esperar por una señal concreta:
#include <unistd.h>
int sigsuspend (const sigset_t *mask);
Funciones para señales
Una señal puede ser tratada o estar pendiente (en
espera de ser tratada)
Un proceso puede bloquear una señal; si se recibe
quedará pendiente.
La señal deja de estar pendiente cuando el proceso la
desbloquea o cambia la rutina de tratamiento a la rutina
por defecto
sigaction permite instalar manejadores de señales
sigprocmask permite especificar un conjunto de señales
sigpending devuelve el conjunto de señales que están
que queremos que el proceso bloquee
bloqueadas y actualmente pendientes.
Máscaras de señales
sigprocmask ( int how, const sigset_t *set,
sigset_t *oset);
how: SIG_BLOCK (bloquear)
SIG_UNBLOCK (desbloquear)
SIG_SETMASK (poner la máscara al
valor expresado en set)
Si *set es NULL, no se realizan cambios
Conjuntos de señales
Para cierta funciones (p.ej. sigaction)
necesitamos especificar un conjunto de
señales:
#include <signal.h>
sigset_t = unsigned long
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signo);
int sigdelset(sigset_t *set, int signo);
int sigmember(const sigset_t *set, int signo);
PROGRAMACIÓN
DE SEÑALES
Manejador de señales
sigaction es más nueva que signal, y es definida por POSIX. Permite ver o
modificar (o ambas cosas) la acción asociada a una señal
#include <signal.h>
struct sigaction {
void (*sa_handler)(int); /* dir. del manejador de señal o SIG_IGN o SIG_DFL */
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
/* señales adicionales a bloquear cuando se maneje ésta*/
}
int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
/* obsoleto */
Funciones de tiempo
#include <sys/time.h>
struct timeval it_interval; /* next value */
struct timeval it_value; /* current value */
struct itimerval {
};
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
int getitimer(int which, struct itimerval *value);
int setitimer(int which, const struct itimerval *value,
struct itimerval *ovalue);
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
unsigned int sleep(unsigned int seconds);
void usleep(unsigned long usec);
Funciones de tiempo
Cada proceso puede tener hasta tres
temporizadores; se ponen con setitimer
alarm genera una señal SIGALRM tras un
número de segundos. La acción por
defecto de SIGALRM es eliminar el
proceso
sleep y usleep suspenden al proceso un
nº de segundos o microsegundos
Ejercicios Prácticos a entregar
1.
2.
3.
4.
NOTA: lo que no se deduzca del enunciado pueden implementarlo como mejor les parezca, pero usen
llamadas al sistema mientras sea posible
Escribir un programa que reciba como parámetro el nº de procesos hijo
que debe crear. Cada proceso hijo deberá dormir un nº aleatorio de
segundos, entre 0 y 30. El padre debe esperar por cada hijo, y presentará
en pantalla su PID a medida que éstos terminen. Cada hijo decide el
tiempo de espera.
Realizar una implementación propia de la función de librería system.
Hacer un programa que imprima un mensaje cuando se pulse Ctrl-C. El
programa debe terminar tras pulsar Ctrl-C x veces. Si no se producen
ninguno en 30 segundos, el proceso deberá terminar.
A) Codificar un programa que envie señales a un proceso. Sintaxis: enviar
señal pid. B) Codificar otro programa que capture las señales SIGINT,
SIGKILL, SIGTERM y SIGUSR1 (muestre un mensaje en pantalla), y que
termine al recibir SIGUSR2.
Comentarios de: Tema 4 - Señales - Sistemas Operativos: Programación de Sistemas (0)
No hay comentarios