Prácticas de Sistemas operativos

Anuncio
Prácticas de Sistemas operativos
David Arroyo Guardeño
Escuela Politécnica Superior de la Universidad Autónoma de Madrid
Segunda Semana: Procesos, Procesos
Padre y Procesos Hijo, familia exec()
1
Entregas
2
Procesos
Fork
Estados de un proceso
Terminación de procesos
Wait
Exec
Entregas
3 Ejercicios 2, 3, 4, 5,6, 7 y 8
☠ Ejercicios 4, 5, 6 y 8
Definición de proceso
7 Instancia de un programa en ejecución
3 Programa = 1 o más procesos
3 Proceso → espacio en memoria + datos:
conjunto de estructuras de datos
7 Elemento central en un SO
7 SO ↔ gestión de procesos
Programa Colección de instrucciones y de
datos almacenados en un fichero
(a.out)
3 Conjunto de cabeceras →
atributos del fichero
3 Texto del programa →
intrucciones lenguaje máquina
3 bss: block started by symbol →
datos a inicializar al arrancar
3 Otras secciones
Proceso Programa leı́do por el núcleo y
cargado en memoria para ejecutarse
3 Segmento de texto →
instrucciones CPU
3 Segmento de datos → variables
estáticas y globales
3 Segmento de pila → marcos de
pila
Marcos de pila
3 Ejecución función → marco de pila
3 Información necesaria para restaurar el
marco de pila anterior a la llamada
3 Contador de programa y puntero de pila
anteriores a la llamada a la función
Modos de ejecución
Modo usuario Pila: argumentos, variables
locales, datos funciones en modo
usuario
Modo supervisor Marcos de pila de las
llamada a sistema
Estructuras de control del SO
7
7
7
7
Tabla de memoria
Tabla de dispositivos de E/S
Tabla de ficheros
Tabla de procesos
Estructuras de control del SO
7 Tabla de memoria
3 Gestión de la memoria principal y secundaria
3 Asignación de memoria a procesos, atributos
de protección de memoria, información para
gestionar memoria
7 Tabla de dispositivos de E/S
7 Tabla de ficheros
7 Tabla de procesos
Estructuras de control del SO
7 Tabla de memoria
7 Tabla de dispositivos de E/S
3 Administración de dispositivos y canales de
E/S
3 Almacena si dispositivo asignado a proceso
3 Estado del dispositivo: información en curso
7 Tabla de ficheros
7 Tabla de procesos
fork→ man fork
7 Proceso en UNIX: entidad tras llamada a
fork. . . salvo el proceso número 0
fork
7 Proceso padre −−→ proceso hijo
7 proceso → PID
fork
7 Proceso 0: tras arrancar el sistema −−→
arrancar
init (proceso 1 −−−−→ /etc/rc*): proceso
0, intercambiador | gestión de la memoria
virtual
Estados de un proceso
1
llamada al sistema o
7
retorno
interrupción
exit
9
2
dormir
despertar
bio
de
cam
o
text
con
orden en ejecución
sı́ mem
oria
1 ⇒ Ejecución modo
usuario
2 ⇒ Ejecución modo
supervisor
3 ⇒ en MP: listo para
ejecutarse
4 ⇒ en MP: durmiendo
5 ⇒ en MS: listo para
ejecutarse
6 ⇒ en MS: durmiendo
3
4
sacar de MP
sacar de MP
6
introducir en MP
5
oria
no
mem
8
fork
# include <u n i s t d . h>
# include < s t d l i b . h>
# include <s t d i o . h>
i n t main ( i n t argc , char ∗ argv [ ] , char ∗env [ ] )
{
i n t i , a =1;
f o r ( i =0; i <10; i ++) {
switch ( f o r k ( ) ) {
case 0 :
a = 3;
p r i n t f ( ” a=%d\n ” , a ) ; break ;
}
p r i n t f ( ‘ ‘ a=%d\n ” , a ) ;
}
exit (0) ;
}
Llamada a fork I
1
2
3
4
5
6
Verificar si espacio en tabla de procesos
Asignar memoria al proceso hijo
Imagen proceso padre → memoria
proceso hijo
Hallar una ranura de proceso libro y
copiar la ranura del proceso padre en él
Asociar mapa de memoria a la tabla del
proceso
Elegir un pid para el proceso hijo
Llamada a fork II
7
8
9
Notificar la existencia del proceso hijo al
kernel y al sistema de archivo
Informar del mapa de la memoria del
proceso hijo al kernel
Enviar mensajes de notificación al
proceso padre y al proceso hijo
¿Por qué puede fallar fork?
Ø Hay que controlar la respuesta de fork
¿Por qué puede fallar fork?
Ø Hay que controlar la respuesta de fork
Ø No hay recuros suficientes
¿Por qué puede fallar fork?
Ø Hay que controlar la respuesta de fork
Ø No hay recuros suficientes
Ø Número máximo de procesos en
ejecución
# include < s t d l i b . h>
# include <s t d i o . h>
i n t main ( i n t argc , char ∗ argv [ ] , char ∗env )
{
int i = 0;
switch ( f o r k ( ) ) {
case −1:
p e r r o r ( ” E r r o r a l c r e a r procesos ” ) ;
e x i t ( −1) ;
break ;
case 0 :
while ( i <10) {
sleep ( 1 ) ;
p r i n t f ( ” \ t \ t Soy e l proceso h i j o : %d\n ” , i ++) ;
}
break ;
default :
while ( i <10){
p r i n t f ( ” Soy e l proceso padre : %d\n ” , i ++) ;
sleep ( 2 ) ;
}
};
}
Terminación de procesos
# include < s t d l i b . h>
void e x i t ( i n t s t a t u s ) ;
...
# include <sys / w a i t . h>
p i d t wait ( int ∗ s t a t l o c ) ;
...
p i d t pid ;
i n t estado ;
...
p i d = w a i t (& estado ) ;
p i d = w a i t ( NULL ) ;
# include <sys / w a i t . h>
# include < s t d l i b . h>
# include <s t d i o . h>
# define NUM PROCESOS 5
int I = 0;
void c o d i g o d e l p r o c e s o ( i n t i d )
{
int i ;
f o r ( i =0; i <50; i ++) {
p r i n t f ( ” Proceso %d : i = %d , I = %d\n ” , i d , i , I ++) ;
}
exit ( id ) ;
}
main ( )
{
i n t p , pid , s a l i d a ;
i n t i d [NUM PROCESOS] = { 1 , 2 , 3 , 4 , 5 } ;
f o r ( p =0; p<NUM PROCESOS; p++) {
pid = fork ( ) ;
i f ( p i d == −1){
p e r r o r ( ” E r r o r a l c r e a r un proceso : ” ) ;
e x i t ( −1) ;
} else i f ( p i d == 0 )
codigo del proceso ( id [ p ] ) ;
}
f o r ( p =0; p < NUM PROCESOS; p++) {
p i d = w a i t (& s a l i d a ) ;
p r i n t f ( ” Proceso %d con i d = %x terminado \n ” , pid , s a l i d a >>8) ;
}
}
# include <u n i s t d . h>
# include <s t d i o . h>
# include < s t d l i b . h>
i n t main ( ) {
p i d t pid , p p i d ;
/ / o b t e n e r e l p i d d e l proceso
pid = getpid ( ) ;
/ / o b t e n e r e l p i d d e l padre d e l proceso
ppid = getppid ( ) ;
p r i n t f ( ” Mi p i d e : %d\n ” , p i d ) ;
p r i n t f ( ” E l p i d de mi padre es %d\n ” , p p i d ) ;
return 0;
}
Familia exec
Ø No se debe realizar ningún tratamiento
tras llamada a exec
Ø Sólo tratamiento de error: exec no vuelve
a la función que la llaman a menos que
se produzca un error
# include <u n i s t d . h>
# include < s t d l i b . h>
# include <s t d i o . h>
i n t main ( i n t argc , char ∗ argv [ ] ) {
/ / Para e j e c u t a r l s , l o s argmuentos de e n t r a d a son : l s − l / b i n
char ∗ l s a r g s [ 4 ] = { ” / b i n / l s ” , ”− l ” , ” / b i n ” , NULL} ;
/ / ejecuta l s
execv ( l s a r g s [ 0 ] , l s a r g s ) ;
/ / a q u i s o l o se l l e g a s i se ha p r o d u c i d o un e r r o r
p e r r o r ( ” execv ha f a l l a d o ” ) ;
r e t u r n 2 ; / / se devuelve codigo de e r r o r
}
}
# include <u n i s t d . h>
# include < s t d l i b . h>
# include <s t d i o . h>
i n t main ( i n t argc , char ∗ argv [ ] ) {
char ∗ l s a r g s [ 4 ] = { ” l s ” , ”− l ” , ” / b i n ” , NULL} ;
execvp ( l s a r g s [ 0 ] , l s a r g s ) ;
p e r r o r ( ” execvp ha f a l l a d o ” ) ;
return 2;
}
# include
# include
# include
# include
# include
<u n i s t d . h>
< s t d l i b . h>
<s t d i o . h>
<sys / t y p e s . h>
<sys / w a i t . h>
i n t main ( i n t argc , char ∗ argv [ ] ) {
char ∗ l s a r g s [ 4 ] = { ” l s ” , ”− l ” , ” / b i n ” , NULL} ;
p i d t pid 0 , pid ;
int status ;
pid 0 = fork ( ) ;
i f ( p i d 0 == 0 ) {
/ ∗ HIIJO ∗ /
p r i n t f ( ” H i j o : e j e c u t a n d o l s \n ” ) ;
execvp ( l s a r g s [ 0 ] , l s a r g s ) ;
p e r r o r ( ” execvp ha f a l l a d o ” ) ;
} else i f ( p i d 0 > 0 ) {
/ ∗ PADRE ∗ /
i f ( ( p i d = w a i t (& s t a t u s ) ) < 0 ) {
p e r r o r ( ” w a i t ha f a l l a d o ” ) ;
exit (1) ;
}
p r i n t f ( ” Padre : he terminado \n ” ) ;
} else {
p e r r o r ( ” Ha f a l l a d o e l f o r k ” ) ;
exit (1) ;
}
r e t u r n 0 ; / / r e t o r n o con e x i t o
}
Referencias
⇒ Francisco M. Márquez. Unix,
Programación Avanzada. Editorial:
Ra-Ma. 3a Edición. ISBN: 84-7897-603-5
Descargar