ps 10 sos_procesos_señales

23
Programación de Sistemas 3.3.1 Administración de procesos: Comunicación entre Procesos: Señales MCC Enrique Ayala Franco

Upload: san-diaz

Post on 29-Jul-2015

45 views

Category:

Software


2 download

TRANSCRIPT

Page 1: Ps 10 sos_procesos_señales

Programación de Sistemas

3.3.1 Administración de procesos:

Comunicación entre Procesos: Señales

MCC Enrique Ayala Franco

Page 2: Ps 10 sos_procesos_señales

Introducción

La multiprogramación necesita que los procesos se comuniquen entre sí para poder colaborar de forma efectiva.

Ya se han mencionado algunos mecanismos utilizando hilos, pero también hay otras formas más primitivas de comunicación entre procesos, por ejemplo las señales.

El sistema utiliza señales para informar a un determinado proceso sobre alguna condición, realizar esperas entre procesos, etc.

Sin embargo, las señales no son suficientes para transmitir toda la información, por ello es necesario incorporar otros mecanismos para compartir datos entre procesos.

2

Page 3: Ps 10 sos_procesos_señales

Introducción

El enfoque más obvio de todos es utilizar ficheros del sistema para poder escribir y leer de ellos, pero esto es lento, poco eficiente e inseguro, aunque muy sencillo de hacer.

El siguiente paso podría ser utilizar una tubería para intercomunicar los procesos a través de él. El rendimiento es superior respecto al enfoque anterior, pero sólo se utilizan en casos sencillos.

Como evolución de todo lo anterior llegó el sistema IPC (Inter Process Communication) de System V, con sus tres tipos de comunicación diferentes: semáforos, colas de mensajes y segmentos de memoria compartida.

3

Page 4: Ps 10 sos_procesos_señales

Introducción

Actualmente IPC del System V ha sido reemplazado por otro estándar, el IPC POSIX.

Ambos implementan características avanzadas de los sistemas de comunicación entre procesos de manera bastante eficiente, por lo que convendría pensar en su empleo a la hora de realizar una aplicación multiproceso bien diseñada.

A continuación veremos algunos conceptos y ejemplos de manejo de señales y también el uso de tuberías y redireccionamiento.

4

Page 5: Ps 10 sos_procesos_señales

Señales en UNIX/LINUX

5

Page 6: Ps 10 sos_procesos_señales

6

Objetivos

Utilizar señales en programas para comprender su influencia y efectos sobre los procesos.

Conocer los tipos de señales POSIX 1b para llevar a cabo operaciones de forma asíncrona.

Page 7: Ps 10 sos_procesos_señales

7

¿Señales?

Hay ocasiones en las que interesa manejar sucesos asíncronos, es decir, que pueden suceder en cualquier momento, no cuando nosotros los comprobemos.

La manera más sencilla de implementar esto es mediante el uso de señales.

La pérdida de la conexión con el terminal, una interrupción de teclado o una condición de error podrían desencadenar que un proceso recibiese una señal. Una vez recibida, es tarea del proceso atrapar o capturarla y tratarla.

Si una señal no se captura, el proceso muere.

Page 8: Ps 10 sos_procesos_señales

8

¿Señales?

Una señal es una notificación por software para un proceso de la ocurrencia de cierto evento.

Cuando ocurre el evento la genera. La señal se deposita cuando el proceso realiza una

acción con base en ella. El tiempo de vida de la señal es desde que se genera

hasta que se deposita. La señal queda pendiente si aún no se deposita. Es

decir pueden haber colas de señales.

Page 9: Ps 10 sos_procesos_señales

9

El envío de señales

En Linux/Unix las señales tienen un nombre simbólico que inicia con SIG. Están definidos en <signal.h>. El la tabla estan las requeridas por POSIX. Los nombres representan enteros mayores que 0.

Símbolo Significado

SIGABRT

SIGALRM

SIGFPE

SIGHUP

SIGILL

SIGINT

SIGKILL

SIGPIPE

SIGQUIT

SIGSEGV

SIGTERM

SIGUSR1

SIGUSR2

Terminación anormal como la iniciada por abort

Señal de espera como la iniciada por alarm

Error en operación aritmética, como la división por cero

Colgado (muerte) de la terminal de control (proceso)

Instrucción de hardware no válida

Señal de atención interactiva

Terminación (no se puede atrapar o ignorar)

Escritura en un entubamiento sin lectores

Terminación interactiva

Referencia no válida de memoria

Terminación

Señal 1 definida por el usuario

Señal 2 definida por el usuario

Page 10: Ps 10 sos_procesos_señales

10

El envío de señales

Algunas señales como SIGFPE y SIGSEGV se generan al ocurrir errores. Otras se generan mediante llamadas específicas, aunque un usuario sólo

puede mandar señales a procesos que posee. Se requiere el ID del usuario real.

Todas las señales pueden ser ignoradas o bloqueadas, a excepción de SIGSTOP y SIGKILL, que son imposibles de ignorar.

La señales se generan desde el shell mediante el comando kill.

Ejemplo: kill

Sintaxis:

Kill –<señal> pid > kill –USR1 3543

Muchas señales tiene por omisión la terminación de procesos.

> kill –l Muestra la lista de señales definidas en el núcleo del sistema

Page 11: Ps 10 sos_procesos_señales

11

Señales y procesos

Un proceso atrapa una señal si éste ejecuta el manejador de señal cuando se deposita una señal.

El programa instala el manejador mediante una llamada sigaction con el nombre de la función a ejecutar.

O un SIG_DFL o un SIG_IGN. SIG_DFL: realiza una acción

preestablecida. SIG_IGN: ignora la señal y se

desecha.

Page 12: Ps 10 sos_procesos_señales

12

El envío de señalesDesde un programa en C:

//envio de señales con la llamada a kill// ¿quién mata a quien??#include <sys/types.h>#include <signal.h>#include <stdio.h>int main (void){int pid;pid = fork();switch (pid){ case 1: perror ("No se ha podido crear el hijo"); break; case 0: printf("Soy el hijo, mi PID es %d y mi PPID es %d\n", getpid(), getppid()); // caso siniestro, el hijo mata a su padre if( kill(getppid(), SIGTERM) == -1) // kill envía la señal al proceso.

perror("Error en kill"); break; default: printf ("Soy el padre, mi PID es %d y el PID de mi hijo es %d\n", getpid(), pid ); printf("%d",kill(pid,SIGTERM) );

// el padre mata al hijo}return 0;}

Page 13: Ps 10 sos_procesos_señales

13

El envío de señales

El comando raise también manda una señal al proceso en primer plano.

raise(SIGUSR1); // enviar señal a sí mismo

Otras formas de hacer esto mismo:pthread_kill(pthread_self(), sig);kill(getpid(), sig);

El comando stty –a informa de las características del dispositivo de entrada estándar, incluyendo configuración de caracteres que generan señales.

> stty –aspeed 38400 baud; rows 24; columns 77; line = 0;intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;eol2 = <undef>; swtch = M-^?; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;….

Page 14: Ps 10 sos_procesos_señales

14

El envío de señales

La función alarm hace que se envíe una señal SIGALRM al proceso que la invoca después de un tiempo determinado en segundos.

No se apilan, si se llama de nuevo se reinicia con el nuevo valor. Su efecto por default es terminar el proceso.

Ejemplo: programa que termina en x segundos.

#include <unistd.h>#include <signal.h>#include <stdio.h>int main (void){alarm(5);printf("Espero 5 segundos para terminar...\n");alarm(1);printf("no mejor 2 segundos ...\n");for(;;){ }printf("No creo llegar hasta aqui...\n");return 0;}

Page 15: Ps 10 sos_procesos_señales

15

Máscaras de señales

Una máscara de señal también determina el tipo de acción a realizar.

La máscara contiene una lista de las señales que en determinado tiempo están bloquedas.

Las señales bloquedas no se desechan, esperan hasta que el proceso las libere y entonces serán depositadas.

Los programas utilizan: sigprocmask para cambiar la máscara y bloquear señales. O un manejador especificando a SIG_IGN como una llamada

sigaction para ignorar señales.

Page 16: Ps 10 sos_procesos_señales

16

Máscaras de señales

Sirven para impedir, de forma temporal, que un proceso deposite la señal, bloqueando las señales.

La mascara de señal indica el conjunto de señales que serán bloqueadas (no ignoradas).

Es de tipo sigset_t. El proceso modifica la máscara mediante el sigprocmask de su señal. Funciones de bloqueo y desbloqueo de grupos de señales:

Int sigemptyset(sigset_t *set); // ninguna señal Int sigfillset(sigset_t *set); // todas las señales Int sigaddset(sigset_t *set, int signo); // agregar una señal al grupo Int sigdelset(sigset_t *set, int signo); // eliminar una señal del grupo Int sigismember(const sigset_t *set, int signo); // 1 si es miembro del

grupo

Page 17: Ps 10 sos_procesos_señales

17

Máscaras de señales//uso de mascaras de señales#include <signal.h>#include <stdio.h>int main (void){sigset_t dossigs;// inicializar mascarassigemptyset(&dossigs);sigaddset(&dossigs, SIGINT); sigaddset(&dossigs, SIGQUIT); sigaddset(&dossigs, SIGKILL); sigaddset(&dossigs, SIGTERM); // aplicar mascaraif(sigprocmask(SIG_BLOCK, &dossigs, NULL))

perror("No se pudo bloquear señales\n");alarm(25);printf("Intenta salir de esto...\n");sleep(10);printf("Termino de dormir\n");// desbloquear señalesif(sigprocmask(SIG_UNBLOCK, &dossigs, NULL))

perror("No se pudo desbloquear señales\n");for(;;){}printf("Algo no se configuro bien...\n");return 0;}

Sintaxis: Sigprocmask(int modo, const sigset_t *set, sigset_t *pset)

El modo puede ser:

SIG_BLOCK: añade para bloquear el conjunto de señales.

SIG_UNBLOCK: borrar una colección se señales del bloqueo.

SIG_SETMASK: establece la máscara de las señales que serán bloqueadas.

Page 18: Ps 10 sos_procesos_señales

18

Como atrapar señales

Se usa la función sigaction para establecer los manejadores de señales de un proceso.

La información del manejador se almacena en una estructura de tipo struct sigaction.

La llamada al sistema tiene tres parámetros: Número de señal o apuntador a función. Apuntador a la estructura de tipo sigaction del nuevo manejador Apuntador a la estructura anterior

En el llamado se llenan los valores con la información anterior de la llamada, si se coloca un apuntador NULL, nada cambia.

Sintaxis: Int sigaction(int señal, const struct sigaction *act, struct sigaction *oact);

Struct sigaction { void()*sa_handler) (); // SIG_DFL, SIG_IGN o apuntador a función sigset_t sa_mask; // señales adicionales se bloquearán durante ejecución

// del manejadorint sa_flags; // banderas especiales y opciones

}

Page 19: Ps 10 sos_procesos_señales

19

Como atrapar señales: ejemplo

#include <signal.h>

static void handler(int signum) { /* Realizar acciones para la señal entregada */ }

int main() { struct sigaction sa; sa.sa_handler = handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART;

/* reiniciar si se interrumpe por el manejador */ if (sigaction(SIGINT, &sa, NULL) == -1) /* manejo de error */; /* mas código */ }

¿Qué pasa después de ejecutar el manejador de señal?

Page 20: Ps 10 sos_procesos_señales

20

Ejemplo mas detallado

#include <stdio.h>#include <stdlib.h>#include <signal.h>

static void manejador1(int signum){ // acciones si se captura señal printf("He capturado la señal ctrl-c\n"); puts("Quieres continuar?: "); char sn=getc(stdin); //leer caracter desde

stdin //fflush(stdin); // limpiar buffer

if(sn=='n' || sn=='N'){ printf("Proceso interrumpido por el usuario");exit(0);}else printf("Continuar hasta que expire mi tiempo...\n");

}

int main() {struct sigaction sa;sa.sa_handler = manejador1;sigemptyset(&sa.sa_mask);sa.sa_flags = SA_RESTART;if( sigaction(SIGINT, &sa, NULL) ==-1) perror("Error al tratar la señal\n");printf("Para interrumpir el proceso ctrl-c\n");alarm(25);for(;;){ // pensando...

}printf("Continuamos con el proceso\n"); return 0;}

Page 21: Ps 10 sos_procesos_señales

21

Ignorar una señal

// Ignorar la señal ctrl-c#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <signal.h>#include <string.h>

char mensaje[]="Se encontro un ctrl-c\n";

static void catch_ctrl_c(int signum){

write(STDERR_FILENO,mensaje,strlen(mensaje));

// write es seguro para llamadas asincronas

}

int main() {struct sigaction sa;//sa.sa_handler = catch_ctrl_c; //

establecer nuevo manejadorsa.sa_handler = SIG_IGN; // ignorar señalsigemptyset(&sa.sa_mask); // no mas

señales bloqueadassa.sa_flags = 0; // ninguna opcion

especialif( sigaction(SIGINT, &sa, NULL) < 0) perror("Error al tratar la señal\n");printf("Para interrumpir el proceso ctrl-

c!!!!!\n");alarm(15);for(;;){ // pensando...}printf("Continuamos con el proceso\n"); return 0;}

Page 22: Ps 10 sos_procesos_señales

Ejemplo con signal

// ejemplo signal.c con funcion signal()

#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <unistd.h>#include <errno.h>

static void manejador1(int signum){// acciones si se captura señalif(signum==SIGINT){printf("He capturado la señal ctrl-c\n");puts("Quieres continuar?: ");char sn[20];fflush(stdin); // limpiar buffer gets(sn); //leer caracter desde stdin //fflush(stdin); // limpiar buffer if(sn[0]=='n' || sn[0]=='N'){printf("Proceso interrumpido por el usuario");exit(0); }else{ printf("Continuar hasta que expire mi tiempo...\n");if( signal(SIGINT, manejador1) ) // necesario volver a especificar señal a capturarperror("Error al tratar la señal\n");}

}else{fprintf(stderr,"Error: esperado=%d, recibido=%d \n", SIGINT, signal);}}

int main() {int n, i=1,j=0;

if( signal(SIGINT, manejador1) ) perror("Error al tratar la senial\n");printf("Para interrumpir el proceso ctrl-c\n");

for(i=1;i<5000; i++){ // pensando...

for(j=0; j<35000; j++)printf("");}printf("Fin de proceso\n"); system("pause");return 0;}

22

Page 23: Ps 10 sos_procesos_señales

23

Ejercicio

Hacer un comando mycat , que despliegue por pantalla el contenido de un archivo de texto, pasado como argumento en la línea de comandos. El programa debe aceptar una interrupción por software en donde se pregunte si se desea continuar con el despliegue o terminar.

Variantes: Mientras se esta desplegando se acepta la señal. Si esta

fuera del despliegue no. Ignorar ctrl-d y otras interrupciones.