Uploaded by yefadiv530

sistemas

Tema
Sistema Operativos
(SSOO)
1.1
Introducción
Grado en Ingeniería Informática
Escuela Politécnica Superior
Índice
•
•
•
•
Definición de sistema operativo
Funciones del SO
Entorno virtual
Un poco de historia
2
Definición de SO/OS
• Un ordenador moderno consta de uno o más procesadores,
una memoria principal, discos, impresoras, un teclado, un
ratón, una pantalla o monitor, interfaces de red y otros
dispositivos de entrada/salida.
• Los ordenadores están equipados con una capa de software
llamada sistema operativo, cuyo propósito es proporcionar a
los programas de usuario acceso a todos los recursos y
administrar cada uno de ellos.
3
Definición de SO/OS
Shell: programa basado en texto con el que los usuarios
generalmente interactúan
GUI (Graphical User Interface; Interfaz
gráfica de usuario): cuando está basado elementos gráficos o
iconos.
4
Definición de SO/OS
•
•
•
•
•
•
•
La mayoría de las computadoras tienen dos modos de operación: modo
kernel y modo usuario.
El SO se ejecuta en modo kernel (modo supervisor).
En el modo kernel, el SO tiene acceso a todo el hardware.
Las otras aplicaciones se ejecutan en modo usuario.
Shell o GUI, es el nivel más bajo del software en modo usuario.
No confundir con los sistemas integrados (como los sistemas
operativos basados en Java que para separar los componentes
utilizan interpretación y no el hardware).
El trabajo del SO es proporcionar una asignación ordenada y
controlada de los procesadores, memorias y dispositivos de E/S, entre
los diversos programas que compiten por estos recursos.
5
Definición de SO/OS
Tres funciones básicas:
• Interfaz con el hardware: gestión de los recursos del ordenador
• Interfaz con las aplicaciones: gestión de los programas en ejecución
(aplicaciones)
• Interfaz con el usuario: ejecución de las órdenes de los usuarios
–
–
–
–
–
–
Gestión de procesos
Gestión de memoria
Gestión del sistema de ficheros
Seguridad
Gestión de los dispositivos de entrada y salida
Networking (TCP/IP, UDP)
6
Entorno virtual
Virtualización del SO
• VirtualBox - Vagrant, VMWare, Parallels, Docker
7
Entorno virtual
8
SO para la asignatura
Descargar SO
9
Un poco de historia
•
Los primeros ordenadores se llamaban mainframes (IBM 704 de 1964).
•
Los usuarios cargaban por
turnos sus programas y datos
mediante tarjetas perforadas
•
El programa se cargaba, se
ejecutaba y terminaba cuando
el programa había concluido…
•
O había fallado antes de
terminar.
•
Sistemas operativos por lotes
(batch).
10
Un poco de historia
11
Un poco de historia
•
Uno de los primeros sistemas operativos modernos con mayor aceptación fue
UNIX
•
•
•
•
Creado en los 70 por Dennis Ritchie y Ken Thompson
•
•
•
Además, un sistema de ficheros unificado y jerárquico
Fue escrito en C (lenguaje creado por Ritchie entre los años 1969-73)
Se caracterizó por su diseño modular.
El SO provee un conjunto de herramientas más o menos sencillas y cada una es
capaz de llevar a cabo ciertas tareas.
Dispone de una Shell o intérprete de comandos.
¿Quién coordina a todas esas herramientas?
–
•
El núcleo o kernel
Además, era portable, multiusuario y multitarea
12
Un poco de historia
•
En los 80 se empezó a pensar que un SO podría usarse en ordenadores de
cualquier tamaño.
•
Nace así MS-DOS: Seattle Computer Products tenía un sistema operativo
conocido como DOS (Disk Operating System; Sistema Operativo en Disco).
•
•
BGates compró DOS y lo ofreció a IBM como DOS/BASIC.
•
Doug Engelbart en el Stanford Research Institute inventó la Interfaz Gráfica de
Usuario GUI.
•
•
•
•
Xerox PARC copió la idea y la utilizó en sus sistemas.
IBM pidió modificaciones y BGates proporcionó MS-DOS (Microsoft Disk
Operating System; Sistema Operativo en Disco de Micro-Soft)
El primer intento de Job surgió de lo visto en PARC
Su segundo intento generó Apple Macintosh.
La evolución de MS-DOS estuvo influenciada por el éxito Apple, de ahí lo de
Windows
13
Un poco de historia
•
•
Entre 1985 y 1995, Windows fue sólo un entorno gráfico encima de MS-DOS.
•
En 1998, se liberó una versión ligeramente modificada de este sistema, conocida
como Windows 98.
•
Sin embargo, tanto Windows 95 como Windows 98 aún contenían una gran
cantidad de lenguaje ensamblador para los procesadores Intel de 16 bits.
En 1995 se liberó una versión independiente de Windows, conocida como
Windows 95.
14
Un poco de historia
•
Otro de los sistemas operativos de Microsoft es Windows NT (NT significa Nueva
Tecnología), que es compatible con Windows 95 en cierto nivel, pero fue
completamente rediseñado en su interior. Es un sistema completo de 32 bits.
•
En los 80 aparecen los ordenadores-consolas con sus propios sistemas
operativos.
Mac OS
Amiga Commodore
15
Un poco de historia
•
•
•
El OS/2 de IBM (aunque también funcionaban con MSDOS y Windows).
La clave: El desarrollo de la GUI (Graphical User Interface)
La del Mac OS 7 fue la primera que soportaba los colores
16
Un poco de historia
17
Recordemos MS-DOS
Escribir "CMD" en aplicaciones
de Windows
18
Kernel
•
•
•
•
•
•
La capa más cercana al hardware se denomina kernel (o núcleo).
Es la parte fundamental del SO.
Gestiona los recursos hardware del sistema
Provee acceso seguro al hardware para los diferentes programas
que se ejecutan.
Y es responsable de decidir cuándo y por cuánto tiempo un
programa puede acceder a cierto hardware.
Se encarga de:
– Gestión de procesos
– Memoria principal
– Memoria de disco
– E/S, Sistema de ficheros
– Seguridad
– Red
19
Arquitecturas del SO
Tipos de arquitecturas del SO según la definición del
kernel:
• Arquitectura kernel monolítico
• Arquitectura microkernel
• Arquitecturas híbridas
20
Arquitecturas del SO: kernel monolítico
•
•
•
•
•
•
Gran parte de la funcionalidad reside en el kernel
Incluyendo planificación, sistema de ficheros, redes,
drivers de dispositivos, gestión de memoria,…
Suele estar implementado como un único proceso
que se ejecuta en modo kernel.
El diseño es modular, como en UNIX
Cuando el sistema arranca se cargan todos los
servicios del SO y se quedan en memoria.
Proceso init.
21
Arquitecturas del SO: kernel monolítico
22
Arquitecturas del SO: kernel monolítico
Desventajas
•
•
•
•
•
•
Podemos tener kernels demasiado grandes.
Los errores en el kernel pueden paralizar el sistema.
Si un driver falla puede hacer caer todo el sistema.
Poco flexible.
Pero es muy rápido.
Cada procedimiento en el sistema tiene la libertad de llamar a
cualquier otro, si éste proporciona cierto cómputo útil que el
primero necesita.
– Al tener miles de procedimientos que se pueden llamar entre sí sin
restricción, con frecuencia se produce un sistema poco manejable y
difícil de comprender.
23
Arquitecturas del SO: Microkernel
•
•
•
•
•
Los procesos de usuario se pueden configurar para
que tengan menos poder, por lo que un error en
ellos tal vez no sería fatal.
Asigna solamente unas pocas funciones al kernel
(modo privilegiado o modo kernel).
Planificación básica, comunicación entre procesos
(IPC),…
El resto sigue una arquitectura cliente – servidor.
Estos se ejecutan en modo usuario o no
privilegiado.
24
Arquitecturas del SO: Microkernel
•
•
Los servicios del SO los proporcionan determinados
procesos, algunas veces llamados servidores.
Los servicios del SO se ejecutan en modo usuario,
y el microkernel los trata como a cualquier otra
aplicación: e.g. Servidor X (GUI), drivers…
25
Cultura general
•
•
•
•
•
La densidad de los errores depende del tamaño del módulo, su
tiempo de vida…
Aproximada en los sistemas industriales formales existen 10
errores por cada 1.000 líneas de código.
Es probable que un SO monolítico de cinco millones de líneas
de código contenga cerca de 50,000 errores en el kernel.
No todos son graves, algunos errores pueden ser: emitir un
mensaje de error incorrecto en una situación poco común.
Los SO tienen tantos errores que los fabricantes de ordenadores
colocan botones de reinicio “reset” en ellas (a menudo en el panel
frontal).
–
No pasa lo mismo en equipos como televisiones, estéreos, coches, etc. pese
a la gran cantidad de software que hay en estos dispositivos.
26
Arquitecturas del SO: Microkernel
•
•
•
•
•
Sólo el microkernel se ejecuta en modo kernel.
El resto se ejecuta como procesos de usuario ordinarios, sin poder
relativamente.
Al ejecutar cada driver de dispositivo y sistema de archivos como
un proceso de usuario separado, un error en alguno de estos
procesos puede hacer que falle ese componente, pero no puede
hacer que falle todo el sistema.
Un error en el driver del dispositivo del audio hará que el sonido
sea confuso o se detenga, pero el ordenador seguirá funcionando.
En un sistema monolítico con todos los drivers en el kernel, un
driver de audio con errores puede hacer uso de una dirección de
memoria inválida y paralizar todo el sistema.
–
Algunos de los microkernel mejor conocidos son Integrity, K42, L4, PikeOS,
QNX, Symbian y MINIX 3.
27
Cultura general: Minix 3
•
•
•
•
MINIX 3 es un sistema de código fuente abierto en conformidad
con POSIX.
–
Sergio: ¿Qué es POSIX?
El microkernel MINIX 3 sólo tiene cerca de 3200 líneas de C y 800
líneas de ensamblador para las funciones de muy bajo nivel (se
usan para atrapar interrupciones y conmutar proceso).
El código de C administra y planifica los procesos, se encarga de
la comunicación entre procesos (al pasar mensajes entre
procesos) y ofrece un conjunto de aproximadamente 35 llamadas
al kernel para permitir que el resto del SO realice su trabajo.
Estas llamadas realizan funciones como: asociar los drivers a las
interrupciones, desplazar datos entre espacios de direcciones e
instalar nuevos mapas de memoria para los procesos recién
creados.
28
Arquitecturas del SO: Microkernel
Ventajas
• Buen diseño
• Protección entre los distintos componentes del
sistema
• Kernel pequeño y flexible
• Pero más lento
29
Arquitecturas del SO: Microkernel
Desventajas
• Se producen muchísimas llamadas al sistema (más
carga en el sistema), más pesado.
• Es difícil la gestión entre procesos
– IPC – Inter-Process Communication
•
•
Y muchos cambios entre los dos modos de
ejecución (modo kernel – modo usuario), que
penalizan el rendimiento
Ejemplo: Amiga OS
30
Arquitecturas del SO: híbrida
•
•
•
•
•
Los kernels híbridos son los usados en la mayoría
de los sistemas operativos comerciales.
Windows (desde Windows NT), Mac OS X.
Es similar al microkernel y al diseño clienteservidor, pero con algunas mejoras.
Se incluye parte del código en modo kernel para
que mejore el rendimiento.
Estas optimizaciones se llevaron a cabo a
mediados de los noventa.
31
Arquitecturas del SO: híbrida
•
•
Se mejoró mucho el rendimiento
Y por ello esta arquitectura fue la adoptada por la
mayoría de los sistemas operativos.
32
Arquitecturas del SO: otros
•
Según el número de procesos simultáneos que
pueden ejecutar:
– Monotarea (MS-DOS)
– Multitarea (el SO debe repartir el tiempo del procesador
entre los diferentes procesos)
•
Según el número de usuarios simultáneos:
– Monousuario( Windows)
– Multiusuario (Linux)
33
Arquitecturas del SO: otros
•
Según el número de procesadores que puede
atender:
– Monoprocesador
– Multiprocesador
•
Según el tipo de arquitectura del procesador que
puede gestionar:
– 16 bits
– 32 bits
– 64 bits
34
Arquitecturas del SO: otros
•
Según el uso:
– Cliente
– Servidor
– Empotrado o
– de tiempo real
•
Según la movilidad:
– Fijos
– Móviles.
35
Bibliografía
•
•
•
CARRETERO, Jesús, GARCÍA, Félix, DE MIGUEL, Pedro, PÉREZ,
Fernando. Sistemas Operativos: una visión aplicada. McGraw-Hill, 2001.
STALLINGS, William. Sistemas operativos: aspectos internos y principios de
diseño. 5ª Edición. Editorial Pearson Educación. 2005. ISBN: 978-84-2054462-5.
TANENBAUM, Andrew S. Sistemas operativos modernos. 3ª Edición.
Editorial Prentice Hall. 2009. ISBN: 978-607- 442-046-3.
36
marlon.cardenas@ufv.es
Grado en Ingeniería Informática
Escuela Politécnica Superior
Tema
Sistema Operativos
(SSOO)
1.2
Elementos del SO
Grado en Ingeniería Informática
Escuela Politécnica Superior
Índice
•
•
•
•
•
Elementos básicos
Registros del procesador
Ejecución de instrucciones
Interrupciones
Jerarquía de la memoria
2
Elementos básicos
3
Elementos básicos
4
Elementos básicos
Procesador: es el “cerebro” del ordenador (CPU), encargado de
obtener las instrucciones de la memoria y ejecutarlas.
El ciclo básico de toda CPU es:
• Obtener la primera instrucción de memoria
• Decodificarla para determinar su tipo y operandos
• Ejecutarla y
• Después obtener, decodificar y ejecutar las instrucciones
subsiguientes.
El ciclo se repite hasta que el programa termina.
5
Elementos básicos
• El acceso a la memoria para obtener una instrucción o
palabra de datos requiere mucho más tiempo que ejecutar
una instrucción.
• Todas las CPU contienen ciertos registros en su interior para
contener las variables clave y los resultados temporales.
• El conjunto de instrucciones generalmente contiene
instrucciones para cargar una palabra de memoria en un
registro y almacenar una palabra de un registro en la
memoria.
• Otras instrucciones combinan dos operandos de los registros,
la memoria o ambos en un solo resultado, como la operación
de sumar dos palabras y almacenar el resultado en un
registro o la memoria.
6
Registros del procesador
Además de los registros generales utilizados para contener variables y
resultados temporales, la mayoría de los ordenadores tienen varios
registros especiales que están visibles para el programador:
• El contador de programa (PC o program counter), el cual contiene
la dirección de memoria de la siguiente instrucción a obtener. Una
vez que se obtiene esa instrucción, el contador de programa se
actualiza para apuntar a la siguiente.
• El apuntador de pila (stack pointer), el cual apunta a la parte
superior de la pila (stack) actual en la memoria. La pila contiene un
conjunto de valores por cada procedimiento al que se ha entrado
pero del que todavía no se ha salido. El conjunto de valores en la
pila por procedimiento contiene los parámetros de entrada, las
variables locales y las variables temporales que no se mantienen
en los registros.
7
Registros del procesador
PSW (Program Status Word; Palabra de estado del programa). Este
registro contiene los bits de código de condición, que se asignan cada
vez que se ejecutan las instrucciones de comparación, la prioridad de
la CPU, el modo (usuario o kernel) y varios otros bits de control.
Los programas de usuario pueden leer normalmente todo el PSW
pero por lo general sólo pueden escribir en algunos de sus campos. El
PSW juega un papel importante en las llamadas al sistema y en las
operaciones de E/S.
• El SO está al tanto de todos los registros. Cuando la CPU se
multiplexa en el tiempo, el SO detiene con frecuencia el programa
en ejecución para (re)iniciar otro.
• Cada vez que detiene un programa en ejecución, el SO debe
guardar todos los registros para poder restaurarlos cuando el
programa continúe su ejecución.
8
Registros del procesador
PC Program Counter:
Contiene la dirección de la
próxima instrucción que será
leída de la memoria.
IR Instruction Register:
contiene la última instrucción
leída.
9
Ejecución de instrucciones
10
Ejecución de instrucciones
11
Ejecución de instrucciones
12
Ejecución de instrucciones
13
Interrupciones
14
Interrupciones
15
Jerarquía de memoria
Capacidad – Velocidad - Coste
• Cuanto mayor tiempo de acceso, mayor coste
• Cuanto mayor capacidad, menor coste
• Cuanto mayor capacidad, menor velocidad de
acceso
16
Jerarquía de memoria
17
Jerarquía de memoria
18
Bibliografía
•
•
•
CARRETERO, Jesús, GARCÍA, Félix, DE MIGUEL, Pedro, PÉREZ,
Fernando. Sistemas Operativos: una visión aplicada. McGraw-Hill, 2001.
STALLINGS, William. Sistemas operativos: aspectos internos y principios de
diseño. 5ª Edición. Editorial Pearson Educación. 2005. ISBN: 978-84-2054462-5.
TANENBAUM, Andrew S. Sistemas operativos modernos. 3ª Edición.
Editorial Prentice Hall. 2009. ISBN: 978-607- 442-046-3.
19
marlon.cardenas@ufv.es
Grado en Ingeniería Informática
Escuela Politécnica Superior
Tema
Sistema Operativos
(SSOO)
1.3
Introducción a Linux
Grado en Ingeniería Informática
Escuela Politécnica Superior
Índice
•
•
•
•
•
Introducción a Linux
GNU/Linux y sus distribuciones
Arranque del ordenador
Arranque secundario
Arranque del SO
2
Introducción a Linux
Algunas cuestiones importantes:
• ¿Quién usa Linux?
• ¿Qué es Linux?
• ¿Qué es Ubuntu, Debian, Red Hat, Suse...? ¿Cuántos
Linux hay?
• ¿Puedo usarlo en casa para escuchar música, ver
películas, chatear, etc.? ¿Echaré algo en falta?
• ¿Por qué tendría que cambiarme a Linux?
• ¿Cómo se aprende Linux?
3
GNU/Linux
•
•
•
•
•
El sistema operativo GNU es un sistema completo de software libre
compatible con Unix. El término GNU proviene de «GNU No es Unix».
Richard Stallman escribió el anuncio inicial del Proyecto GNU en
setiembre de 1983.
Al principio de los años ochenta, casi todo el software era privativo, lo
que significa que tenía dueños que prohibían e impedían la cooperación
entre usuarios. De ahí que fuera necesario el Proyecto GNU.
Si no existe un sistema operativo libre, ni siquiera se puede comenzar a
usar un ordenador sin recurrir al software privativo. Así, el primer
elemento en la agenda del software libre tenía que ser un sistema
operativo libre.
El sistema operativo era compatible con Unix porque el diseño en
general ya estaba probado y era portable, y porque la compatibilidad
facilitaba a los usuarios de Unix el cambio de Unix a GNU.
Fuente original: https://www.gnu.org/distros/free-distros.html
4
GNU/Linux
•
•
•
•
Un sistema operativo similar a Unix incluye un núcleo, compiladores,
editores, procesadores de texto, software de correo, interfaces gráficas,
bibliotecas, juegos y muchas otras cosas.
En 1990 ya se contaba con los componentes principales excepto uno, el
núcleo.
En 1991, Linus Torvalds creó Linux basándose en Minix, una pequeña
implementación de UNIX para PC, el cual fue escrito totalmente en C por
A. Tannenbaum.
Linus anunció su primera versión oficial 0.02, el 5 de Octubre de 1991.
En 1992 se convirtió en software libre.
Fuente original: https://www.gnu.org/distros/free-distros.html
5
Linux
• Consta básicamente del Kernel, el shell y el compilador gcc.
• Cuando se habla de Linux, realmente se hace referencia al Kernel
o núcleo del sistema. El resto de aplicaciones que corren sobre ese
kernel (formando usualmente una distribución) debería llamarse
GNU / Linux.
La idea de usar un pingüino fue de Alan Cox, uno de los
desarrolladores del kernel de Linux. Larry Ewing se encargó de
dibujarlo usando GIMP, en el año 1996.
Su nombre es Tux (Torvalds Linux)
Fuente original: https://www.gnu.org/distros/free-distros.html
6
Distribuciones 100% GNU/Linux
•
•
La palabra «libre» en «software libre» se refiere a libertad, no al precio.
Se puede o no pagar un precio por obtener software de GNU.
Una vez que se obtiene el software, se tienen cuatro libertades
específicas para usarlo:
– La libertad de ejecutar el programa como se desee;
– La libertad de copiar el programa y dárselo a amigos o compañeros de trabajo;
– La libertad de cambiar el programa como se desee mediante el acceso completo al
código fuente
–
La libertad de distribuir una versión mejorada, ayudando así a construir la comunidad
(si se redistribuye software de GNU, se puede cobrar una tarifa por el acto físico de
efectuar la copia, o bien regalar copias)
Fuente original: https://www.gnu.org/distros/free-distros.html
7
Distribuciones 100% GNU/Linux
Fuente original: https://www.gnu.org/distros/free-distros.html
8
Distribuciones 100% GNU/Linux – Ligeras
• Distribuciones para dispositivos con recursos limitados, como por
ejemplo un router inalámbrico.
• Estas distribuciones no son autónomas sino que deben poder ser
desarrolladas y compiladas sobre una de las distribuciones libres
completas de la lista anterior, posiblemente con el auxilio de
herramientas de desarrollo libres distribuidas junto a la misma.
Fuente original: https://www.gnu.org/distros/free-distros.html
9
Distribuciones GNU/Linux – Sin avalar
Excepto donde se indica, ninguna de las distribuciones que se incluyen en la
siguiente lista respeta las pautas en al menos dos aspectos importantes:
•
No adoptan ninguna política para incluir únicamente software libre, ni para
eliminar el software que no sea libre cuando se detecta. La mayoría de estas
distribuciones no tienen en absoluto una política clara sobre qué software
aceptan o rechazan. Hay distribuciones que sí tienen una política, pero
lamentablemente no son lo suficientemente estrictas, como se explica a
continuación.
•
El núcleo que distribuyen (en la mayoría de los casos, Linux) incluye blobs:
piezas de código compilado distribuidas sin el código fuente,
generalmente firmware para hacer funcionar algún dispositivo.
10
Distribuciones GNU/Linux – Sin avalar
Arch GNU/Linux
Canaima
CentOS
Debian GNU/Linux
Fedora
Gentoo GNU/Linux
Mandriva GNU/Linux
Manjaro GNU/Linux
Mint GNU/Linux
openSUSE
Red Hat GNU/Linux
Slackware
SteamOS
SUSE GNU/Linux Enterprise
Tails
Ubuntu GNU/Linux
Otros:
Android
Sistema BSD
Chrome OS
Haiku
/e/
LineageOS
ReactOS
https://www.gnu.org/distros/common-distros.html
11
SO para la asignatura
Descargar SO
12
Arranque del ordenador i
•
Cada Pentium contiene (en su tarjeta madre) un programa conocido
como BIOS (Basic Input Output System, Sistema básico de entrada y
salida) del sistema.
– El BIOS contiene software de E/S de bajo nivel, incluyendo procedimientos para leer
el teclado, escribir en la pantalla y realizar operaciones de E/S de disco, entre otras
cosas.
•
•
Hoy en día está contenido en una RAM tipo flash que es no volátil pero el
SO puede actualizarla cuando se encuentran errores en el BIOS.
La BIOS (firmware) realiza la inicialización básica del hardware (POST:
encendido y autocomprobación (power on self test)) y pasa el control
del sistema al siguiente paso.
– Primero hace pruebas para ver cuánta RAM hay instalada y si el teclado junto con
otros dispositivos básicos están instalados y responden en forma correcta.
–
Empieza explorando los buses ISA y PCI para detectar todos los dispositivos
conectados a ellos.
13
Arranque del ordenador ii
•
•
•
•
•
•
Un firmware es un software que maneja físicamente al hardware durante
el arranque.
Está cargado en la memoria ROM (Read-Only Memory) del ordenador,
no en el disco duro.
Read-only memory (ROM) es un tipo de memoria no volátil que se usa
en equipos y otros dispositivos electrónicos.
Permite solo la lectura de la información y no su escritura.
Las ROM modernas sí se pueden reprogramar y se llaman EPROM
(Erasable Programmable Read-Only Memory)
Entre ellas también las flash ROM.
14
Arranque del ordenador iii
•
El BIOS determina el dispositivo de arranque, para lo cual prueba una
lista de dispositivos almacenada en la memoria CMOS.
– El usuario puede cambiar esta lista si entra a un programa de configuración del BIOS,
justo después de iniciar el sistema.
–
•
•
•
Por lo general, se hace un intento por arrancar: Disco flexible, Unidad de CD, USB,
Red, HDD, otros.
La BIOS busca el dispositivo de inicio y pasa el control al primer sector
físico del dispositivo conocido como Master Boot Record o MBR.
Los dos primeros sectores del disco duro (los primeros 512 bytes)
contienen el MBR. El MBR es básicamente una tabla de particiones
cuyas entradas son las particiones primarias y lógicas que hay en el
disco duro.
Este sector contiene un programa que por lo general examina la tabla de
particiones al final del sector de arranque, para determinar qué partición
está activa.
15
Arranque secundario
•
•
•
•
Después se lee un cargador de arranque secundario de esa partición.
Este cargador lee el sistema operativo de la partición activa y lo inicia.
El sistema operativo consulta al BIOS para obtener la información de
configuración.
Para cada dispositivo, comprueba si tiene el driver correspondiente. De
no ser así, pide al usuario que inserte un CD-ROM que contenga el
driver (suministrado por el fabricante del dispositivo).
Una vez que tiene los drivers de todos los dispositivos, el sistema
operativo los carga en el kernel. Después inicializa sus tablas, crea los
procesos de segundo plano que se requieran, y arranca un programa de
inicio de sesión o GUI.
16
Arranque secundario
Cargador de arranque secundario.
• El cargador de arranque (bootloader), en nuestro caso GRUB, es el
encargado de la segunda fase del proceso de arranque.
• GNU GRUB (GNU GRand Unified Bootloader) es un gestor de arranque
múltiple, desarrollado por el proyecto GNU que nos permite elegir qué
sistema operativo arrancar de los instalados.
• Grub se puede instalar en el MBR o en los primeros sectores de una
partición primaria activa (es decir, arrancable), identificada como /boot
• Si tengo varios sistemas operativos y quiero que Grub sea capaz de
arrancar todos, debo instalarlo en el MBR.
• Este /boot puede estar en la misma partición que la / o en otra partición
(igual que /home por ejemplo, que lo separamos de / )
17
Particiones para el arranque
•
•
•
Partición primaria: partición que si está activa, puede ser usada
para arrancar un sistema operativo.
Partición extendida: partición física que no se puede usar a
menos que sea dividida en particiones lógicas.
Particiones lógicas: subdivisiones de la extendida.
Imagen tomada de: http://elsitioandres.blogspot.com/2011/09/particion-y-multiple-instalacion-de.html
18
Particiones para el arranque
•
•
•
•
•
•
•
Se pueden tener hasta cuatro particiones primarias o tres primarias
más una extendida.
La extendida se puede dividir en hasta 128 particiones lógicas.
Podemos indicar que el sistema se inicia desde una partición primaria
activa del disco duro primario.
Solo puede haber una partición primaria marcada como activa.
Partición primaria: partición que si está activa, puede ser usada para
arrancar un sistema operativo.
La partición / puede estar en una primaria (activa o no) o incluso en una
lógica.
Pero /boot debe estar en una partición que sea arrancable (primaria
activa).
19
Arranque del SO i
•
•
•
•
•
•
Si se instala primero Windows y luego Linux, éste sobrescribe el gestor
de arranque de Windows(BCD o Boot Configuration Data en Windows)
No hay problema porque Grub reconocerá que están instalado Windows
y meterá una entrada en el menú de arranque para poder arrancarlo
En caso contrario no. Si instalo primero Linux y luego Windows, el gestor
de arranque sobrescribe el Grub y luego no puede inicial Linux.
Se carga el sistema de archivos raíz en disco duro.
El programa init es ejecutado en primer lugar con el PID=1 preparando
el proceso de arranque principal para el comienzo de muchos procesos.
Muchos de estos procesos son demonios.
– PID Proccess ID: es el número entero usado por el kernel de un SO para identificar
un proceso de forma unívoca.
20
Arranque del SO ii
•
•
•
•
•
Un demonio (o daemon, Disk And Execution MONitor) que generalmente
se carga en memoria, y está esperando alguna señal (proveniente del
núcleo o si es un servicio de red, un cliente que se conecte) para
despertarse y ejecutar las funciones necesarias para tratarla.
Los daemons que tengamos arrancados no ocupan la CPU mientras no
es estrictamente necesario.
Es un proceso que se ejecuta en background (es decir, en segundo
plano).
Todos los demonios tienen un shell script situado en el directorio
/etc/init.d/ que permite iniciarlo, pararlo o ver su estado de ejecución.
Iniciar/parar un demonio:
– sudo /etc/init.d/nombre_demonio {star, stop, restart}
– Sudo service nombre_demonio {star, stop, restart}
21
Arranque del SO iii
•
•
•
Desde Debian jessie (Debian 8) y las últimas versiones de Ubuntu, se
cambió el arranque de init (al estilo Unix System V) por otra forma en la
que quien gestiona todo, es un proceso llamado systemd.
Este proceso systemd hace lo mismo que init
– Álvaro: prueba el siguiente comando en la terminal de Ubuntu: ps -- pid=1
– Explica a toda la clase para qué sirve este comando.
– Cómo se te ve mucha disposición, prueba este comando: arch, explica qué muestra.
Systemd es un conjunto de herramientas, librerías y servicios diseñados
para llevar la llevar la administración y configuración central de los
sistemas Linux e interactuar directamente con el núcleo de los mismos.
– https://en.wikipedia.org/wiki/Category:Linux_distributions_without_systemd
– Silvia: consulta el enlace anterior y comenta de qué trata.
22
Arranque del SO Debian/Ubuntu
•
•
•
Systemd se encarga de arrancar todos los demás procesos durante el
inicio del sistema.
Cuáles se arrancan depende del nivel de ejecución en el que nos
encontremos (también llamado runlevel)
Por defecto, hay 7 runlevels posibles, desde el runlevel 0 hasta el
runlevel 5, aunque esto es posible modificarlo.
– Init 0:
– Init 1:
– Init 2-4:
– Init 5:
– Init 6:
23
Arranque del SO Debian/Ubuntu
•
•
•
•
•
•
Init 0: ejecuta los procesos necesarios para parar el sistema
Init 1: modo monousuario. Se ejecuta para realizar tareas de
mantenimiento como root con unos servicios (o demonios) mínimos
Init 2-4: modo multiusuario. Por defecto están todos configurados iguales
(es decir, arrancan los mismos demonios), y están preparados por si
queremos modificarlos (añadiendo o quitando demonios).
Init 5: Multiusuario con entorno gráfico (sistema X Window)
Init 6: Parecido al 0 pero sirve para reiniciar
Los comandos halt, reboot, shutdown o poweroff lo único que hacen
es llamar al nivel de ejecución 0 o 6
24
Arranque del SO Debian/Ubuntu
La forma como se organizan estos daemons en cada nivel de ejecución es
muy simple:
• Cada nivel de ejecución tiene un directorio situado en /etc/rcX.d/ donde
la “X” es el número de runlevel.
• En estos directorios encontramos enlaces simbólicos a los shell scripts
de los daemons situados en /etc/init.d/, que nos sirven para indicar al
sistema si queremos iniciar o parar el daemon al que apuntan.
• Con el mismo nombre del enlace se identifica la acción a realizar: si el
enlace empieza por “S” (Start) indicamos que queremos iniciar el
daemon, mientras que se empieza por “K” (Kill) indica que queremos
pararlo.
• Si el nombre no empieza por ninguna de estas letras, el sistema no hace
nada con él.
25
Arranque del SO Debian/Ubuntu
•
•
•
•
Después de esta letra se pone un número de 2 cifras entre “00” y “99”,
que indica el orden de inicio o parada de los mismos.
Este orden es importante, ya que algunos daemons necesitan que otros
estén en ejecución antes de ser iniciados.
Al cambiar de nivel de ejecución, el sistema inspeccionará los daemons
del directorio correspondiente y empezará, primero, parando los
daemons indicados y después iniciará los demás.
Consulta por ejemplo:
– ls /etc/rc0.d
– ls /etc/rc5.d
26
Bibliografía
•
•
•
CARRETERO, Jesús, GARCÍA, Félix, DE MIGUEL, Pedro, PÉREZ,
Fernando. Sistemas Operativos: una visión aplicada. McGraw-Hill, 2001.
STALLINGS, William. Sistemas operativos: aspectos internos y principios de
diseño. 5ª Edición. Editorial Pearson Educación. 2005. ISBN: 978-84-2054462-5.
TANENBAUM, Andrew S. Sistemas operativos modernos. 3ª Edición.
Editorial Prentice Hall. 2009. ISBN: 978-607- 442-046-3.
27
marlon.cardenas@ufv.es
Grado en Ingeniería Informática
Escuela Politécnica Superior
Tema
1.4
Sistema Operativos
(SSOO)
Shell Scripts I
Grado en Ingeniería Informática
Escuela Politécnica Superior
Índice
•
•
Bash
Shell scripts
2
Introducción a Bash
Es la interfaz entre el usuario final y el Sistema Operativo.
• No es el S.O.
• Existen múltiples versiones y podemos averiguar cual tenemos
instalada haciendo.
Existen múltiples Shells en Unix:
• Bourne shell (sh), C shell (csh), Korn shell (ksh), TC Shell (tcsh)
• Bourne Again shell (bash).
La más popular es la “bash” shell.
• bash incorpora las prestaciones más útiles de la Korn shell (ksh) y
la C shell (csh).
• Ofrece mejoras funcionales sobre otras shells desde el punto de
vista de programación y de su uso interactivo.
3
Introducción a Bash: tipos de shell
Las shells más conocidas son:
bash, GNU Bash o Bourne-Again Shell es una implementación GNU de la shell bsh, desarrollada
por Stephen Bourne en Laboratorios Bell de AT&T en 1978. La shell bash fue desarrollada por
GNU en 1989.
csh o C shell, desarrollada por Bill Joy en la Universidad de Berkeley. Se distribuyó por primera
vez en 1979 junto con las BSD.
dash o Debian Almquist shell es una implementación GNU de la shell Almquist Shell o ash de las
BSD. Desarrollada por Herbert Xu a principios de 1997, adoptando el nombre dash en 2002.
ksh o Korn shell, desarrollada por David Korn en en los Laboratorios Bell de AT&T en 1980.
sh, desarrollada por Ken Thompson en 1971 en los Laboratorios Bell de AT&T.
Es uno de las primeros desarrollos de shell que, 50 años después, continúa utilizándose.
tcsh o TENEX shell, desarrollada por Ken Greer entre finales de los años 70 y principios de los
años 80. Es una mejora de la shell csh y en 1984 reemplazo a esta en las FreeBSD.
4
Introducción a Bash: tipos de shell
zsh, desarrollada por Paul Falstad en 1990, cuando era estudiante en la Universidad de
Princeton, como actualización y reemplazo de la shell bsh o Bourne Shell.
A lo largo de la vida del sistema operativo macOS (Mac OS X, OS X y macOS) se han utilizado
las shells tcsh, bash y zsh.
Apple utiliza, en las últimas versiones del sistema operativo macOS (macOS 10.15 Catalina y
macOS 11 Big Sur), la shell zsh que reemplaza a la shell bash.
Consultar la versión de la Shell:
$echo $SHELL
$bash --versión
$echo $BASH_VERSION
$whereis bash
$cat /etc/shells
5
Introducción a Bash
Cambiar la Shell actual a bash: usa el comando chsh
•
Desde la Terminal se pueden listar todas las shells disponibles en el SO con el comando
cat
•
/etc/shells
Para cambiar la shell desde la Terminal se utiliza el comando
chsh -s /bin/nombre_de_la_Shell
(reiniciar la terminal)
6
Introducción a Shell Scripts
bash no es únicamente una excelente shell por línea de comandos.
• Es un lenguaje de scripting que permite utilizar las capacidades de la
shell para automatizar muchas tareas que implicarían distintos comandos
introducidos de manual.
Scripting no es un lenguaje de programación:
• Los lenguajes de programación son por lo general, más potentes y
•
•
mucho más completos que los lenguajes de scripting.
Los lenguajes de programación parten del código fuente, el cual luego es
compilado para crear los ejecutables.
Un ejecutable permite que los programas sean portables entre diferentes
SSOO.
7
Comandos Linux
•
•
•
•
•
•
•
•
•
•
•
•
chmod
rm -rf
cd $HOME
mv
chown
ls –al
clear, echo
tree, lstree
cat, nano
who –u/b
whereis, pwd
ps –a | grep bash
8
Introducción a Shell Script
•
Un lenguaje de scripting también comienza por el código fuente, pero no
se compila en un ejecutable
• En su lugar, un intérprete lee cada instrucción del fichero fuente y las
ejecuta de forma secuencial.
• Los programas interpretados son por lo general son más lentos que los
compilados.
Ejecuta tu primer script
Crea un fichero llamado “scr01.sh”:
#!/bin/bash
echo “Hola Mundo”
Interpretar: indicar que el fichero es interpretado por bash para su ejecución
Permisos: es importante hacer que el script sea ejecutable:
$ chmod 700 scr01.sh
$ ls –l:
-rwx------ scr_01.sh
9
Introducción a Shell Script
Ejecuta tu segundo script
Crea un fichero llamado “scr02.sh”:
#!/bin/bash
mkdir log_apache
mkdir log_tomcat
cp ./servers/server1/*.log log_apache/
cp ./servers/server2/*.log log_tomcat/
$ chmod 700 scr02.sh
$ ls –l:
-rwx------ scr_02.sh
10
Shell Script: variables
•
•
•
•
•
•
•
Los valores se almacenan como cadenas de texto.
No es necesario declarar las variables, con asignarle un valor es suficiente.
Los operadores matemáticos que convierten las variables en número para
realizar cálculos.
Para consultar el valor de una variable se antepone el símbolo $ al
nombre.
#!/bin/bash
cadena = “¡Hola Gente!” #esto es un comentario
echo $cadena
No existe el casting de los tipos de las variables, por lo que se podrá
asignar a una misma variables diferentes valores sin importar su tipo.
Se recomienda usar el mismo tipo de datos a una variable dentro de un
mismo script.
El carácter de escape de la bash \ mantiene el carácter siguiente.
11
Shell Script: uso de comillas
•
•
•
Las cadenas de textos deben ir acompañadas de comillas simples o
dobles.
El uso de comillas dobles “…” permite referenciar otras variables dentro de
la cadena, e.g. cadena = “Tu edad es $edad”
El uso de comillas simples permite mostrar una cadena sin la posibilidad
de referenciar otras variables dentro de la misma cadena.
– cadena = ‘Tu edad es $edad’
Ejercicio:
Mostrar la siguiente cadena de texto:
El valor de la variable ‘edad’ es “31”
12
Bibliografía
•
•
•
CARRETERO, Jesús, GARCÍA, Félix, DE MIGUEL, Pedro, PÉREZ,
Fernando. Sistemas Operativos: una visión aplicada. McGraw-Hill, 2001.
STALLINGS, William. Sistemas operativos: aspectos internos y principios de
diseño. 5ª Edición. Editorial Pearson Educación. 2005. ISBN: 978-84-2054462-5.
TANENBAUM, Andrew S. Sistemas operativos modernos. 3ª Edición.
Editorial Prentice Hall. 2009. ISBN: 978-607- 442-046-3.
13
marlon.cardenas@ufv.es
Grado en Ingeniería Informática
Escuela Politécnica Superior
Tema
Sistema Operativos
(SSOO)
1.5
Shell Scripts II
Grado en Ingeniería Informática
Escuela Politécnica Superior
Índice
•
Shell scripts
2
Shell Script: variables
•
•
•
•
•
•
•
Los valores se almacenan como cadenas de texto.
No es necesario declarar las variables, con asignarle un valor es suficiente.
Los operadores matemáticos que convierten las variables en número para
realizar cálculos.
Para consultar el valor de una variable se antepone el símbolo $ al
nombre.
#!/bin/bash
cadena = “¡Hola Gente!” #esto es un comentario
echo $cadena
No existe el casting de los tipos de las variables, por lo que se podrá
asignar a una misma variables diferentes valores sin importar su tipo.
Se recomienda usar el mismo tipo de datos a una variable dentro de un
mismo script.
El carácter de escape de la bash \ mantiene el carácter siguiente.
3
Shell Script: uso de comillas
•
•
•
Las cadenas de textos deben ir acompañadas de comillas simples o
dobles.
El uso de comillas dobles “…” permite referenciar otras variables dentro de
la cadena, e.g. cadena = “Tu edad es $edad”
El uso de comillas simples permite mostrar una cadena sin la posibilidad
de referenciar otras variables dentro de la misma cadena.
– cadena = ‘Tu edad es $edad’
Ejercicio:
Mostrar la siguiente cadena de texto:
El valor de la variable ‘edad’ es “31”
4
Shell Script: variables entre procesos
•
•
El comando export pone una variable en el entorno de forma que sea
accesible por los procesos hijos.
Si el proceso hijo modifica el valor de la variable cadena, no modificará
el valor original del proceso padre. Verificarlo cambiando el valor de
cadena desde un proceso hijo.
Observa este ejemplo:
$ cadena=libro
$ bash # Ejecuta una nueva shell (proceso hijo)
$ echo $cadena # No debería mostrar nada cadena
$ exit # Regresa al proceso padre
$ export cadena
$ bash
$ echo $cadena
libro # El resultado es...
5
Shell Script: variables
Hay dos tipos de variables de entorno:
– Variables locales
– Variables del entorno
Las Variables del entorno se establecen por el sistema y se pueden encontrar
utilizando el comando env.
Las variables de entorno contiene valores especiales.
Las variables del entorno se definen en /etc/profile,
/etc/profile.d/ y ~/.bash_profile.
Estos ficheros son de inicialización y son leídos cuando se invoca la bash
shell.
Cuando la login shell sale, la bash lee ~/.bash_logout
6
Shell Script: variables
HOME: argumento por defecto (directorio home) del comando cd.
PATH: el path de búsqueda de comandos. Es una lista de
directorios separados por ‘:’ en los que se busca cuando se teclea
cualquier comando.
Normalmente, introducimos los comandos de la siguiente manera:
– $ ./trash.sh
Estableciendo PATH=$PATH:. Nuestro directorio de trabajo se
incluye en path de búsqueda de comando y simplemente podremos
introducir:
– $ trash.sh
7
Shell Script: variables
•
•
•
•
•
•
LOGNAME: contiene el nombre de usuario
HOSTNAME: contiene el nombre de la máquina
MACHTYPE: sistema hardware
UID: contiene el id del usuario que no puede ser modificado
SHLVL: contiene el nivel de anidamiento de la shell
PS1: secuencia de caracteres monstrados antes del prompt
– \t hora
– \d fecha
– \w directorio actual
– \W última parte del directorio actual
– \u nombre de usuario
– \$ caracter del prompt
8
Shell Script: otras variables
•
•
•
•
•
•
$#: número argumentos
$*: todos los argumentos de la shell
$@: semejante a la variable anterior
$-: opciones suministradas a la shell
$?: devolver valor de la última orden ejecutada
$!: identificación del proceso de la última orden que
comenzó con &
9
Shell Script: Exit
Exit se puede utilizar para finalizar la ejecución de un script o
para devolver un valor, el cuál estará disponible al proceso
padre del script.
• Cuando un script termina con exit sin parámetros, el estado
de salida será el del último comando ejecutado en el script.
• Cuando se ejecuta el script con el comando exit con
parámetros, la sintaxis es: exit nnn, donde nnn=0-255 y el
estado de salida es nnn
10
Shell Script: Operadores
+ suma, - resta, * multiplicación, / división, ** exponenciación
% módulo
Prueba lo siguiente:
$ a=(5+2)*3
$ echo $a
$ b=2**3
$ echo $a+$b
11
Shell Script: Leer de teclado
Read permite solicitar un valor de entrada para almacenarlo en
una variable.
Opciones
read –s (no hace echo de la entrada)
read –nN (acepta sólo N caracteres de entrada)
read –p “mensaje” (muestra un mensaje)
read –tT (acepta una entrada por un tiempo máximo de T segundos)
Ejemplo (copiar.sh)
#!/bin/bash
echo -n “Introduzca nombre de fichero a copiar: ”
read fichero
cp -i $fichero
echo “El fichero $fichero ha sido copiado!“
12
Shell Script: Leer de teclado
Ejemplo:
$ read –s –n1 -p “si (S) o no (N)?” respuesta
si (S) o no (N) ? S
$ echo $respuesta
S
13
Shell Script: Ejecutar comandos
El símbolo ` tiene un uso diferente de ´. Se utiliza para sustitución de
instrucciones. Es decir si dentro de un script aparece el texto `comando`
entonces se ejecutará lo orden que está entre las `
$ LISTA=`ls`
$ echo $LISTA # Lista los archivos
fichero.sh, scr01.sh
Otra forma de realizar la sustitución de comandos: $(comando)
$ LISTA=$(ls)
$ echo $LISTA
hola.sh leer.sh
ls $( pwd )
ls $( echo /bin )
14
Shell Script: Estructura de control
Condicional: la forma más básica es:
– if [expresión];
then
instrucciones
elif [expresión];
then
instrucciones
else
instrucciones
fi
– Las secciones elif(else if) y else son opcionales
15
Shell Script: Expresiones
Una expresión puede ser: comparación de cadenas, comparación numérica,
operadores de fichero y operadores lógicos y se representa mediante
[expresión]:
Comparación de cadenas:
=
!=
-n evalúa si la longitud de la cadena es superior a 0
-z evalúa si la longitud de la cadena es igual a 0
Ejemplos:
[ s1 = s2 ] (true si s1 es igual a s2, sino false)
[ s1 != s2 ] (true si s1 no es igual a s2, sino false)
[ s1 ] (true si s1 no está vacía, sino false)
[ -n s1 ] (true si s1 tiene longitud mayor que 0, sino false)
[ -z s2 ] (true si s2 tiene longitud 0, sino false)
16
Shell Script: Expresiones
Comparación cadenas:
=
!=
#!/bin/bash
echo -n “Introduzca su nombre de usuario: ”
read login
if [ “$login” = “$USER” ]; then
echo “Hola, $login. Cómo está hoy?”
else
echo “Tú no eres $USER!!!”
fi
17
1
Shell Script: Expresiones
Comparación numérica:
-eq
-ge
-le
-ne
-gt
-lt
Ejemplos:
[ n1 -eq n2 ]
[ n1 -ge n2 ]
#!/bin/bash
echo -n “Introduzca un número 1 < x < 10: "2
read num
if [ “$num” -lt 10 ]; then
if [ “$num” -gt 1 ]; then
echo “$num*$num=$(($num*$num))”
else
echo “¡Número fuera de rango!”
fi
else
echo “¡Número fuera de rango!”
fi
[ n1 -le n2 ]
[ n1 -ne n2 ]
[ n1 -gt n2 ]
[ n1 -lt n2 ]
18
Shell Script: Expresiones
Operadores de archivos:
-d verifica si el path dado es un directorio
-f verifica si el path dado es un archivo
-s verifica si el path dado en un link simbólico
-e verifica si el fichero existe
-s verifica si el fichero tiene un tamaño mayor a 0
-r verifica si el fichero tiene permiso de lectura
Ejemplos:
[ -d nombre_fichero]
[ -f nombre_fichero ]
[ -e nombre_fichero ]
[ -s nombre_fichero ]
[ -r nombre_fichero ]
[ -w nombre_fichero ]
[ -x nombre_fichero ]
-w verifica si el fichero tiene permiso de escritura
-x verifica si el fichero tiene permiso de ejecución
#!/bin/bash
if [ -f /etc/fstab ]; then
3
cp /etc/fstab .
echo “Hecho.”
else
echo “Archivo /etc/fstab no existe.”
exit 1
fi
19
Shell Script: Expresiones
Operadores lógicos:
! = NOT
-a = AND
-o = OR
&& = AND
|| = OR
#!/bin/bash
echo -n “Introduzca un número entre 1 < x <
10:”
read num
if [ “$num” -gt 1 –a “$num” -lt 10 ];
then
echo “$num*$num=$(($num*$num))”
else
echo “Número introducido incorrecto !”
fi
#!/bin/bash
echo -n “Introduzca un número 1 < x < 10: "
read num
if[ “$number” -gt 1 ] && [ “$number” -lt 10 ];
then
echo “$num*$num=$(($num*$num))”
else
echo “Número introducido incorrecto !”
fi
20
5
4
Shell Script: parámetros
Los parámetros posicionales se asignan desde la shell cuando se invoca.
Parámetro posicional “N” se referencia como “${N}”, o “$N” cuando “N” lo
forma un sólo dígito
Parámetros especiales
$# número de parámetros pasados
$0 devuelve el nombre del shell script que se está ejecutando y su ubicación en el
sistema de archivos
$* devuelve en una cadena de caracteres todos los parámetros pasados al script
$@ devuelve un array con los parámetros pasados al script
6
#!/bin/bash
echo “$#; $0; $1; $2; $*; $@”
Así puedes probar tu script No 6
$ ./scr06.sh estudiante1 estudiante2
./scr06.sh; estudiante1; estudiante2; estudiante1 estudiante2; estudiante1 estudiante2
21
Shell Script: case
case $var in
val1)
instrucciones;;
val2)
instrucciones;;
*)
instrucciones;;
esac
#!/bin/bash
echo -n “Introduzca un número entre 1 < x
< 10: ”
read x
case $x in
1) echo “Valor de x es 1.”;;
2) echo “Valor de x es 2.”;;
3) echo “Valor de x es 3.”;;
4) echo “Valor de x es 4.”;;
5) echo “Valor de x es 5.”;;
6) echo “Valor de x es 6.”;;
7) echo “Valor de x es 7.”;;
8) echo “Valor de x es 8.”;;
9) echo “Valor de x es 9.”;;
0 | 10) echo “Número incorrecto.”;;
*) echo “Valor no reconocido.”;;
esac
22
Shell Script: for
for
for var in lista
do
statements
done
#!/bin/bash
let sum=0
for num in 1 2 3 4 5
do
let “sum = $sum + $num”
done
echo $sum
7
8
#!/bin/bash
for x in papel lapiz boli; do
echo “El valor de la variable x es: $x”
sleep 1
done
23
Shell Script: for
for
for var in lista
do
statements
done
#!/bin/bash
lista=“antonio luis maria pepa”
for x in $lista
do
echo “El valor de la variable x es: $x”
sleep 1
done
9
10
#!/bin/bash
for x in “papel A4” “lapiz STADTLER” “boli BIC”; do
echo “El valor de la variable x es: $x”
sleep 1
done
24
Shell Script: for
#!/bin/bash
# Lista todos los ficheros del directorio /bin
for x in /bin
do
ls -l “$x”
done
11
#!/bin/bash
# Lista todos los ficheros del directorio actual
for x in *
do
ls -l “$x”
sleep 1
done
12
#!/bin/bash
read –p “Introduzca el nombre de un directorio: ”
directorio
echo “enlaces simbólicos en el directorio
$directorio “
for fichero in $( find $directorio -type l )
do
echo "$fichero"
done
13
25
Shell Script: arrays
Crear un array
mascota[0]=perro
mascota[1]=gato
mascota[2]=pez
pet=( perro gato pez )
Longitud máxima de un array son 1024 elementos.
Para extraer una entrada del array ${array[i]}
$ echo ${mascota[0]}
perro
$ echo ${mascota[2]}
pez
26
Shell Script: arrays
Para extraer todos los elementos se utiliza un asterisco:
echo ${array[*]}
Para saber cuántos elementos hay en el array:
echo ${#array[*]}
Podemos combinar los arrays con bucles utilizando
for:
for x in ${array[*]}
do
echo ${array[$x]}
done
27
Shell Script: arrays
Estructura tipo C alternativa para for
for (( EXPR1 ; EXPR2 ; EXPR3 ))
do
instrucciones
done #!/bin/bash
echo “Introduzca un número: ”; read x
14
let sum=0
for (( i=1 ; $i<$x ; i=$i+1 )) ; do
let “sum = $sum + $i”
done
echo “La suma de los primeros $x números es: $sum”
28
Shell Script: while
while expresion_evalua_a_true
do
instrucciones
done
#!/bin/bash
15
echo –n “Introduzca un número: ”; read x
let sum=0; let i=1
while [ $i –le $x ]; do
let “sum = $sum + $i”
let “i = $i + 1”
done
echo “La suma de los primeros $x números es: $sum”
29
Shell Script: until
until expresion_evalua_a_true
do
instrucciones
done
#!/bin/bash
echo “Introduzca un número: ”; read x
echo ;
until [ “$x” -le 0 ]; do
echo $x
x=$(($x –1))
sleep 1
done
echo ; echo FIN
30
16
Shell Script: funciones
#!/bin/bash
function check() {
17
if [ -e "/home/$1" ]
then
return 0
else
return 1
fi
}
echo “Introduzca el nombre del archivo: ” ; read x
if check $x
then
echo “$x existe !”
else
echo “$x no existe !”
fi
31
Shell Script: hacer debug
Bash ofrece dos formas de depurar los shell scripts
-v : muestra cada línea completa del script antes de ser
ejecutada
-x : muestra cada línea abreviada del script antes de ser
ejecutada
Uso: #!/bin/bash –v, o #!/bin/bash –x
#!/bin/bash –x
echo –n “Introduzca un número: ”; read x
let sum=0
for (( i=1 ; $i<$x ; i=$i+1 )) ; do
let “sum = $sum + $i”
done
echo “La suma de los $x primeros números es: $sum”
32
Bibliografía
•
•
•
CARRETERO, Jesús, GARCÍA, Félix, DE MIGUEL, Pedro, PÉREZ,
Fernando. Sistemas Operativos: una visión aplicada. McGraw-Hill, 2001.
STALLINGS, William. Sistemas operativos: aspectos internos y principios de
diseño. 5ª Edición. Editorial Pearson Educación. 2005. ISBN: 978-84-2054462-5.
TANENBAUM, Andrew S. Sistemas operativos modernos. 3ª Edición.
Editorial Prentice Hall. 2009. ISBN: 978-607- 442-046-3.
33
marlon.cardenas@ufv.es
Grado en Ingeniería Informática
Escuela Politécnica Superior
Tema
Sistema Operativos
(SSOO)
2.1
Definición y
Gestión de procesos
Grado en Ingeniería Informática
Escuela Politécnica Superior
Índice
•
•
•
•
Definición de proceso
Gestión de procesos
Estados de los procesos
Gestión de procesos en Linux
2
Definición de proceso
Un proceso puede informalmente entenderse como un programa
en ejecución.
•
Formalmente un proceso es "Una unidad de actividad que
se caracteriza por la ejecución de una secuencia de
instrucciones, un estado actual, y un conjunto de
recursos del sistema asociados".
3
Definición de proceso
La gestión de procesos es una de las tareas fundamentales de
cualquier sistema operativo
El sistema operativo debe:
• Asignar recursos a los procesos
• Permitir el intercambio de información entre los mismos
• Proteger los recursos de un proceso del resto
• Y facilitar la sincronización de los procesos
4
Definición de proceso
¿Es lo mismo un programa que un proceso?
5
Definición de proceso
Para que el SO pueda llevar estas tareas, este mantiene una
estructura de datos para cada proceso que describe:
• Su estado
• Los recursos que posee
Esto permite al sistema operativo imponer un control sobre los
procesos (es decir, gestionar los procesos)
6
Gestión de procesos
Principal problema:
El cuello de botella que se forma por la diferencia de
velocidad entre el procesador y los dispositivos de entrada y
salida (E/S).
Si un proceso que está usando el procesador necesita
realizar una operación de E/S (por ejemplo, escribir en disco
duro), el SO debe dar paso a otro proceso para que el
procesador no esté inactivo.
El SO sería algo parecido a un policía de tráfico.
7
Gestión de procesos
En resumen, el SO debe gestionar el uso que cada proceso
hace de los recursos hardware del sistema (en este tema, el
procesador y el disco duro), repartiendo los tiempos que
necesitan cada uno de los procesos.
8
Estados de los procesos
Un proceso puede estar en los siguientes estados principales:
•
•
•
•
•
Ejecución: es un proceso que está haciendo uso del procesador.
Bloqueado: no puede ejecutarse hasta que un evento externo
sea llevado a cabo.
Listo: ha dejado disponible al procesador para que otro proceso
pueda ocuparlo.
Nuevo: proceso que se acaba de crear, pero que aún no ha sido
admitido en la lista de procesos ejecutables por el sistema
operativo (no ha sido aún cargado en la memoria principal).
Terminado: el proceso ha sido excluido por el sistema operativo,
bien porque se detuvo o bien porque fue abandonado por alguna
otra razón
9
Gestión de procesos en Linux
¿Cómo se gestionan los procesos en Linux?
La orden más importante es la orden ps.
• Lista todos los procesos en ejecución del sistema
• Y toda su información asociada
10
Gestión de procesos en Linux
Con ps a secas podemos ver los procesos del usuario (si en
vez del UID queréis verlo con el username se pone ps u, y
además sale %CPU y %MEM)
¿Cómo identifico mi UID?
$echo $UID
11
Gestión de procesos en Linux
• Ver todos los procesos del sistema escribo: ps -ef
• Para ver las primeras líneas: ps -ef | head -5
• Valores importantes mostrados en ps (ps –ef):
–
–
–
–
UID – usuario que ha lanzado el proceso
PID: ID del proceso
PPID: ID del proceso padre
CMD: orden que ha lanzado el proceso
12
Gestión de procesos en Linux
•
•
Con ps –u joselito se pueden ver qué procesos está
ejecutando el usuario joselito
Con ps –e se pueden ver todos los procesos del sistema
13
Gestión de procesos en Linux
Otra opción muy común para lanzar la orden ps es
ps aux
• La lista muestra muchos procesos, para ello usa
el comando en conjunción con grep (si quiero
filtrar) o con more (paginar)
–
–
•
ps aux | grep bash
ps aux | more
También, para ver las primeras líneas:
–
ps aux | head -5
14
Gestión de procesos en Linux
Valores importantes mostrados en ps aux:
USER – usuario que ha lanzado el proceso
PID: ID del proceso
%CPU y %MEM: % uso de CPU y memoria
TIME: tiempo de CPU acumulado
STAT
15
Gestión de procesos en Linux
Estado del proceso (STAT) → ver man ps
S: (interruptible sleep): en pausa, esperando un evento para
continuar
R: (running o runnable): en ejecución
T: Marks a stopped process. Parado
U: process in uninterruptible wait
I (iddle): Marks a process that is idle (sleeping for longer than about
20 seconds)
Z: Marks a dead process (a “zombie') ver man ps
16
Gestión de procesos en Linux
Procesos padre y procesos hijos
• Para verlos, lanzar varias instancias del shell con la
orden bash, y ver con ps -ef los PID y el PPID
• ps -ef | grep bash (ver su PID y el PPID)
Para ver quién es su padre:
• ps -p 538 (o el PPID que sea)
• bash (lanzo otro proceso hijo bash)
• ps -ef | grep bash (ver su PID y el PPID, que será el PID
del primer bash)
17
Gestión de procesos en Linux
Para mostrar el árbol de procesos se usa la orden pstree
Posiblemente habrá que instalarlo con apt-get install
Forma de ejecutarlo:
• pstree -p (aparecen los PIDs)
• pstree 1581 (el árbol de un proceso en concreto con PID
1581)
• También se puede ver algo parecido con ps axjf
18
Gestión de procesos en Linux
Más información de los procesos:
< High-priority (not nice to other users)
N Low-priority (nice to other users)
+ Is in the foreground process group
19
Gestión de procesos en Linux
La orden top: Muestra valores actualizándose
instantáneamente
• Parecido al monitor del sistema y al administrador de
tareas (task manager)
• Pero desde aquí no se pueden administrar los procesos
Opciones en top:
top –d 5 (Donde 5 es el número de segundos a transcurrir
entre cada muestreo)
top –o %CPU (Donde %CPU es el valor por el que vamos a
ordenar los procesos )
20
Gestión de procesos en Linux
Trabajos: listado de trabajos (procesos creados por un
usuario) ejecutándose
• También se le llaman tareas
• Se usa la orden jobs
A cada trabajo se le asigna un número N como identificador.
Un trabajo (proceso) puede ejecutarse en:
• Modo foreground (primer plano) o
• Backgroung (segundo plano)
21
Gestión de procesos en Linux
Background: $ nombre_del_proceso &
Ejemplo:
• Orden sleep: la orden sleep ejecutaría un proceso
después del tiempo especificado
Por ejemplo: sleep 10; date
Mostraría la fecha a los diez segundos
22
Gestión de procesos en Linux
Background: $ nombre_del_proceso &
Ejemplo:
• Orden sleep: la orden sleep ejecutaría un proceso
después del tiempo especificado
Por ejemplo: sleep 10; date
Mostraría la fecha a los diez segundos
Prueba:
• sleep 60 & > /dev/null
• Para verlo: jobs (identificado con [1])
• ps aux | grep sleep (identificado con su PID)
23
Gestión de procesos en Linux
Suspender un trabajo en foreground: [ctrl-z]
• sleep 60
• ctrl-z
Ver jobs
24
Gestión de procesos en Linux
Para pasar un trabajo de foreground a background (y
viceversa):
• Primero suspenderlo [ctrl-z]
• Lo veo en jobs
Escribir luego
• $ bg %n (fg para foreground), siendo n el número de
trabajo que se ve en jobs
• No hace falta poner %
25
Gestión de procesos en Linux
Si sleep 60 es el trabajo 2, lo paso a foreground así:
• fg 2
Lo suspendo otra vez: [Ctrl-z]
Lo veo en jobs
Lo paso a background así:
• bg 2
Parar un trabajo foreground antes de que acabe: [Ctrl-C]
• No lo veré en jobs
26
Gestión de procesos en Linux
Otro ejemplo:
• Ejecuto top en foreground
• ¿Qué diferencia hay entre pulsar [Ctrl+c] y [Ctrl+z]
• Una vez suspendido reanudarlo en foreground
• Pasarlo a background desde foreground
• ¿Cómo lo paro ahora, estando en background?
27
Gestión de procesos en Linux
No puedo usar [Ctrl+c]
• Debo matar la tarea: kill %1
Otra opción sería matar el proceso. Para ello debería
buscar antes el PID y luego hacer un kill a ese PID, sin el %
• ps aux | grep top
• kill 1767 (1767 = PID del proceso)
Fijaos que no se pone el %
¿Qué pasa si se pone kill 1 en vez de kill %1?
28
Gestión de procesos en Linux
¿Quién puede matar un proceso?
• Sólo el propietario de ese proceso
• Recordad que lo puedo saber por el UID asociado al
proceso
Cuando se ejecuta la orden kill, el SO envía una señal al
proceso (señal 15 por defecto o de terminación de proceso)
• Existen más de 20 señales
• Existen algunos procesos como el propio Shell que no
mueren cuando reciben esta señal
• ¿Qué hacemos entonces para matarlo?
29
Gestión de procesos en Linux
Intenta matar la shell
• Kill de la muerte: sudo kill -9 PID
Ejemplo:
• Identificar con ps –ef y grep el PID del shell
También se puede hacer poniendo solo ps
Intentar matarlo con un kill
• Matarlo con el kill -9
30
Gestión de procesos en Linux
Al igual que Apache, multitud de servicios necesitan ser
reiniciados, y la mayoría de ellos responde al argumento
‘HUP’ (Hang up) de kill.
Mediante el siguiente comando, el servicio perteneciente a
Apache, se reiniciará y volverá a cargar el fichero de
configuración, permitiéndonos ver si los cambios han surtido
efecto y volviendo a dar servicio a los usuarios.
• kill –HUP [PID de Apache]
31
Gestión de procesos en Linux
Si queremos matar un proceso por su nombre y no por su
PID usaremos la orden killall
• killall sleep
• killall Firefox
Esta orden mataría el proceso Firefox y todos los que
dependen de él.
• Otro ejemplo con sleep y shell scripts: la orden who
(también w sólo) dice quién está en el sistema.
• Mediante (sleep 3600; who >> log) & crearíamos un log
con el registro de usuarios en el sistema una hora
después.
32
Gestión de procesos en Linux
¿Cómo funciona?
• Se crea un proceso en modo background que duerme
(suspende su operación) durante 3600 segundos; luego
se despierta, ejecuta la orden who y coloca la salida en
un fichero de nombre log.
Otro ejemplo: mediante este script:
(while true
do
sleep 60
finger
done) &
Finger dice qué usuarios han hecho login en el sistema
33
Gestión de procesos en Linux
Prioridad: se usa la orden nice
• La orden nice en Linux sirve para ejecutar un programa
con su prioridad de programación modificada.
• Se le asignará de esta forma más o menos tiempo de
CPU y se ejecutará por lo tanto más lento (o más rápido)
• Los valores van desde el -20 (mayor prioridad al proceso)
al 19 (menor prioridad)
• Solo los usuarios root pueden modificar la prioridad de
todos los procesos.
• Los demás usuarios podrán modificar la prioridad de los
procesos de los que son propietarios.
34
Gestión de procesos en Linux
Prioridad
Aumentar la prioridad:
• nice -n-20 orden (-20 es la máxima prioridad)
Disminuir la prioridad
• nice -n19 orden (19 es la mínima prioridad)
Necesitamos ser root (o sudo) para cambiar la prioridad
35
Gestión de procesos en Linux
Prioridad
Ejemplo:
sudo su
nice -n-19 sleep 120 &
ps –l (ver su prioridad PRI)
nice -n19 sleep 130 &
ps –l (ver su prioridad PRI)
36
Gestión de procesos en Linux
Prioridad
• Podemos restablecer la prioridad de este proceso, con
pid 898, con el comando renice
• renice 898 (898 sería el pid de sleep; verlo con ps al)
• Su prioridad volvería a ser 0
37
Gestión de procesos en Linux
Prioridad
• Si se observa que un usuario del sistema está ocupando
mucho tiempo de CPU, se puede asignar a todos los
procesos que este lance una prioridad más baja (o más
alta)
Haga la siguiente prueba:
• Como root: renice +20 -u alumno
• Salir de root (logout)
• Y al volver a ser el usuario, lanzad top &
• Ver su prioridad con ps al
38
Gestión de procesos en Linux
Otras órdenes:
time: la orden time se utiliza para determinar la duración de
ejecución de un determinado comando.
• Da el tiempo del sistema, el tiempo del usuario y el
tiempo real
• Ya lo veremos con los algoritmos de gestión de procesos
39
Bibliografía
•
•
•
CARRETERO, Jesús, GARCÍA, Félix, DE MIGUEL, Pedro, PÉREZ,
Fernando. Sistemas Operativos: una visión aplicada. McGraw-Hill, 2001.
STALLINGS, William. Sistemas operativos: aspectos internos y principios de
diseño. 5ª Edición. Editorial Pearson Educación. 2005. ISBN: 978-84-2054462-5.
TANENBAUM, Andrew S. Sistemas operativos modernos. 3ª Edición.
Editorial Prentice Hall. 2009. ISBN: 978-607- 442-046-3.
40
marlon.cardenas@ufv.es
Grado en Ingeniería Informática
Escuela Politécnica Superior
Tema
Sistema Operativos
(SSOO)
2.1
Gestión de procesos
Grado en Ingeniería Informática
Escuela Politécnica Superior
Índice
•
•
•
•
•
Creación de procesos.
Terminación de procesos.
Ciclo de vida de un proceso.
Tipos de planificación.
Algoritmos de planificación
2
Creación de procesos
Los SO proveen mecanismos para que los procesos puedan
crear otros procesos → Llamada al sistema
El proceso de creación se puede repetir recursivamente
creándose una “estructura familiar” → Árbol de procesos
Esto no quiere decir que
la comunicación entre
padre e hijo sea natural y
sencilla, NO.
Asignación de recursos al nuevo proceso:
– Los obtiene directamente del SO
– El padre debe repartir sus recursos con el proceso hijo o compartir todos
o parte de ellos con él.
Se evita así que un proceso bloquee el sistema multiplicándose
indefinidamente.
3
Creación de procesos
Cuando se crea un proceso:
– En términos de ejecución
– El padre continua ejecutándose en paralelo con
su/s hijo/s.
– El padre espera a que alguno o todos sus hijos
hayan terminado.
– En términos del espacio en memoria
– El proceso hijo es un clon del proceso padre.
– El proceso hijo tiene ya un programa cargado en
memoria.
4
Creación de procesos
¿Qué necesita saber el SO sobre cada proceso?
• Un proceso necesita la memoria suficiente para
almacenar el programa y los datos que utiliza
• Atributos para que el SO pueda controlar el proceso. A
estos atributos se les llama Bloque de Control del
Proceso (BCP)
• A los programas, datos y atributos se le llama imagen
del proceso
5
Creación de procesos
¿Qué tiene en concreto el BCP?
•
•
Identificación del proceso: PID, PPID y UID del usuario que
creó el proceso (ver orden top)
Información del estado del procesador – Si se suspendió el
proceso, se guardan aquellos registros del procesador que
permitan reanudarlo más adelante.
¿Dónde se guarda la imagen del proceso?
• En memoria principal (RAM) – si está en ejecución todo o
parte tiene que estar aquí
• En memoria de disco (memoria virtual) – si está suspendido,
todo. Si no, puede estar solo parte de la imagen.
6
Creación de procesos
En la familia Unix se distingue entre crear
procesos y ejecutar nuevos programas.
• La llamada al sistema para crear un nuevo
proceso se denomina fork().
• Esta llamada crea una copia casi idéntica del
proceso padre.
 Ambos procesos, padre e hijo, continúan ejecutándose en
paralelo.
 El padre obtiene como resultado de la llamada a fork() el pid
del hijo y el hijo obtiene 0.
 Algunos recursos no se heredan (p.ej. señales pendientes).
7
Creación de procesos
El proceso hijo puede invocar la
llamada al sistema exec*()
– sustituye su imagen en memoria por
la de un programa diferente
El padre puede dedicarse a crear más
hijos, o esperar a que termine el hijo
– wait() lo saca de la cola de “listos”
hasta que el hijo termina
8
Creación de procesos
Ineficiencias del modelo fork()
– Se copian muchos datos que podrían compartirse
– Si al final se carga otra imagen, todavía es peor porque todo lo
copiado se deshecha.
Muchos UNIX usan COW
– Copy-on-Write es una técnica que retrasa o evita la copia de los
datos al hacer el fork.
– Los datos se marcan de manera que si se intentan modificar se
realiza una copia para cada proceso (padre e hijo).
– Ahora fork() sólo copia la tabla de páginas del padre (no las
páginas) y crea un nuevo BCP para el hijo.
9
Creación de procesos
www.u3cm.es
10
Creación de procesos
www.u3cm.es
11
Creación de procesos
www.u3cm.es
12
Terminación de procesos
Cuando un proceso termina todos los recursos asignados
son liberados:
– memoria, ficheros abiertos, entradas en tablas,...
y el kernel notifica al proceso padre el evento.
Un proceso puede terminar de 2 formas:
• Voluntariamente: Llamada al sistema exit()
• Involuntariamente:
– Excepciones: división por cero, violación de segmento
– Abortado por el usuario (ctrl-c) u otro proceso (kill), es
decir, señales que no puede manejar o ignorar.
13
Terminación de procesos
Cuando un proceso termina pueden suceder dos
cosas:
– Sus hijos no se ven afectados
– Todos los hijos acaban también → terminación en
cascada (Ej. VMS)
En Unix,
– Los hijos del proceso terminado pasan a depender
del proceso init
– El proceso finalizado pasa a estado Zombie hasta
que el proceso padre recoge su código de
finalización.
14
Terminación de procesos
Las terminación de un proceso y la eliminación
de su BCP son tareas diferenciadas:
– Cuando el padre obtiene la información del hijo,
se procede a eliminar las estructuras de datos
– Llamada al sistema wait()
• Bloquea al proceso hasta que termina el/un hijo
• Devuelve el PID del hijo finalizado
15
Ciclo de vida de un proceso
www.u3cm.es
16
Ciclo de vida de un proceso
• Cuando existen muchos procesos en
ejecución el rendimiento puede bajar por
excesiva paginación.
– Solución: El Sistema Operativo puede expulsar
totalmente procesos al área de intercambio del
disco.
• Introduce nuevos estados de los procesos.
– Bloqueado y suspendido.
– Listo y suspendido.
17
Ciclo de vida de un proceso
18
www.u3cm.es
Tipos de planificación (Niveles)
Planificación a corto plazo
– Selecciona el siguiente proceso a ejecutar.
Planificación a medio plazo
– Selecciona qué procesos se añaden o se retiran
(expulsión a swap) de memoria principal.
Planificación a largo plazo
– Realiza el control de admisión de procesos a ejecutar.
– Muy usada en sistemas batch.
19
Tipos de planificación
• No apropiativa.
– El proceso en ejecución conserva el uso de la
CPU mientras lo desee.
• Apropiativa.
– El sistema operativo puede expulsar a un proceso
de la CPU.
20
Puntos de decisión de planificación
Momentos en los que se puede decidir la planificación de
un proceso:
1.
2.
3.
Cuando un proceso se bloquea en espera de un evento
– Realización de una llamada al sistema.
Cuando se produce una interrupción.
– Interrupción del reloj.
– Interrupción de fin de E/S.
Fin de proceso.
Planificación no apropiativa: 1 y 3.
– Windows95, MacOS anteriores a versión 8.
Planificación apropiativa: 1, 2 y 3.
21
Pilas de procesos
Los procesos listos para ejecutar se mantienen
en una cola.
Alternativas:
• Cola única.
• Colas por tipos de procesos.
• Colas por prioridades.
22
Algoritmos de planificación (Medidas)
• Utilización de CPU:
– Porcentaje de tiempo que se usa la CPU.
– Objetivo: Maximizar.
• Productividad:
– Número de trabajos terminados por unidad de
•
tiempo.
– Objetivo: Maximizar.
Tiempo de retorno (Tq)
– Tiempo que está un proceso en el sistema. Instante
final (Tf) menos instante inicial (Ti).
– Objetivo: Minimizar.
23
Algoritmos de planificación (Medidas)
• Tiempo de servicio (Ts):
– Tiempo dedicado a tareas productivas (cpu,
entrada/salida). Ts = TCPU+ TE/S
• Tiempo de espera (Te):
– Tiempo que un proceso pasa en colas de espera.
Te = Tq – Ts
• Tiempo de retorno normalizado (Tn):
– Razón entre tiempo de retorno y tiempo de servicio.
Tn = Tq/Ts
– Indica el retardo experimentado.
24
Algoritmos de planificación
Grupo 1: Asignación FCFS
First to Come First to Serve: Primer en llegar primero en servir.
– Algoritmo no apropiativo.
– Penaliza a los procesos cortos.
Grupo 2: Asignación SJF
Shortest Job First: Primero el trabajo más corto.
–
–
–
–
Algortimo no apropiativo.
Selecciona el trabajo más corto.
Solamente se puede aplicar si se conoce de antemano la duración de cada
trabajo.
Posibilidad de inanición:
• Si continuamente llegan trabajos cortos, los trabajos largos nunca llegan
a ejecutarse.
25
Algoritmos de planificación
Grupo 3: Cíclico o Round-Robin
– Mantiene una cola FIFO con los procesos listos para ser ejecutados.
– Un proceso recibe el procesador durante un cuanto o rodaja de
tiempo.
– Algoritmo apropiativo.
Grupo 4: Planificación en Windows
Principales características:
– Basado en prioridades y uso de cuantos de tiempo.
– Planificación apropiativa.
– Planificación con afinidad de procesador.
26
No olvidemos que…
•
•
•
•
•
•
La creación de un proceso implica la creación de su imagen
de memoria y de su BCP.
Un proceso pasa por distintos estados durante su ejecución.
El sistema operativo realiza la planificación de los procesos.
La planificación puede ser apropiativa y no apropiativa.
Los distintos algoritmos de planificación de procesos pueden
favorecer más o menos a un tipo de procesos.
Los sistemas operativos modernos usan planificación
apropiativa.
27
Bibliografía
•
•
•
•
U3CM, www.u3cm.es, Material de la asignatura Sistemas Operativos
CARRETERO, Jesús, GARCÍA, Félix, DE MIGUEL, Pedro, PÉREZ,
Fernando. Sistemas Operativos: una visión aplicada. McGraw-Hill, 2001.
STALLINGS, William. Sistemas operativos: aspectos internos y principios de
diseño. 5ª Edición. Editorial Pearson Educación. 2005. ISBN: 978-84-2054462-5.
TANENBAUM, Andrew S. Sistemas operativos modernos. 3ª Edición.
Editorial Prentice Hall. 2009. ISBN: 978-607- 442-046-3.
28
marlon.cardenas@ufv.es
Grado en Ingeniería Informática
Escuela Politécnica Superior
Tema
3.1
Sistema Operativos
(SSOO)
Procesos e Hilos
Grado en Ingeniería Informática
Escuela Politécnica Superior
Índice
•
•
•
Procesos e hilos.
Multiprocesamiento simétrico.
Micronúcleos.
2
Procesos e hilos
• En los SO tradicionales, cada proceso tiene un espacio
•
•
de direcciones y un solo hilo de control. De hecho, ésa es
casi la definición de un proceso.
Un proceso es algo más complejo de lo que se ha visto
hasta este momento.
Contiene dos conceptos diferentes y potencialmente
independientes:
– uno relativo a la propiedad de recursos y
– Otro relativo a la ejecución.
• Esta distinción ha llevado al desarrollo de los hilos o
threads.
3
Procesos e hilos
Características de un proceso:
1. Recursos: un proceso incluye un espacio de
direcciones virtuales para el manejo de la imagen del
proceso.
– La imagen de un proceso es la colección de programa, datos,
–
–
pila y atributos definidos en el bloque de control del proceso.
A un proceso se le puede asignar control o propiedad de
recursos tales como la memoria principal, canales E/S,
dispositivos E/S y archivos.
El sistema operativo se encarga de la protección para evitar
interferencias no deseadas entre procesos en relación con los
recursos.
4
Procesos e hilos
Características de un proceso:
2. Planificación y ejecución: la ejecución de un
proceso sigue una ruta de ejecución (traza) a través
de uno o más programas.
– La ejecución puede estar intercalada con ese u otros procesos.
– Un proceso tiene un estado de ejecución: Ejecutando, Listo,
–
etc..
Tiene asignada una prioridad de activación, siendo ésta la
entidad que planifica y activa el sistema operativo.
5
Procesos e hilos
Estas dos características son independientes y podrían ser
tratadas como tales por el sistema operativo.
Para distinguir estas dos características, la unidad que se
activa se suele denominar hilo (thread), o proceso ligero,
mientras que la unidad de propiedad de recursos se suele
denominar proceso o tarea.
6
Procesos e hilos
¿Por qué definir hilos?
•
•
•
Muchas aplicaciones realizan varias actividades a la vez.
Algunas de ésas se pueden bloquear de vez en cuando.
Al descomponer una aplicación en varios hilos secuenciales que se
ejecutan en cuasi-paralelo, el modelo de programación se simplifica.
¿No era lo mismo para los procesos?
•
•
•
Sí, se pensaba en procesos paralelos.
Los hilos añaden un nuevo elemento: la habilidad de las entidades
en paralelo de compartir un espacio de direcciones y todos sus
datos entre ellas.
Esta habilidad es esencial para ciertas aplicaciones, razón por la
cual no funcionará el tener varios procesos (con sus espacios de
direcciones separados).
7
Procesos e hilos
¿Por qué definir hilos?
•
•
•
•
•
Los hilos son más ligeros que los procesos.
Más fáciles de crear y de destruir (de 10 a 100 veces más rápido).
Los hilos no producen aumento del rendimiento cuando todos están
ligados en la CPU.
Cuando hay una gran cantidad de cálculos y operaciones de E/S, el
uso de hilos permite solapar con lo cual agiliza la velocidad de la
aplicación.
Los hilos son útiles en los sistemas con varias CPU, donde si es
posible un verdadero paralelismo.
8
Multihilo
Capacidad de un sistema operativo de dar soporte a
múltiples hilos de ejecución en un solo proceso.
El enfoque de un solo hilo de ejecución por proceso, en el
que no se identifica con el concepto de hilo, se conoce como
estrategia monohilo.
–
–
–
MS-DOS solo soporta un único proceso y un único hilo.
Java soporta un único proceso con múltiples hilos.
Windows, Solaris, Os soporta múltiples procesos y múltiples hilos.
9
Multihilo
10
Multihilo
Ejemplos de uso de un sistema Multihilo.
• Trabajo en primer plano y en segundo plano:
–
Esta forma de trabajo a menudo incrementa la velocidad que se
percibe de la aplicación, permitiendo al programa solicitar el siguiente
mandato antes de que el mandato anterior esté completado.
• Procesamiento asíncrono:
–
Los elementos asíncronos de un programa se pueden implementar
como hilos.
• Velocidad de ejecución:
–
Un proceso Multihilo puede computar una serie de datos mientras que
lee los siguientes de un dispositivo. Aunque un hilo pueda estar
bloqueado por una operación de E/S mientras lee datos, otro hilo se
puede estar ejecutando.
11
Multihilo
Ejemplos de uso de un sistema Multihilo.
• Estructura modular de programas:
–
Los programas que realizan diversas tareas o que tienen varias
fuentes y destinos de entrada y salida, se pueden diseñar e
implementar más fácilmente usando hilos.
12
Multihilo
La planificación y la activación se realizan a nivel de hilo; por ello
la mayor parte de la información de estado relativa a su ejecución
se mantiene en estructuras de datos que están a su nivel.
13
Multihilo – Estado de los hilos
•
•
Los principales estados de los hilos son: Ejecutando, Listo y Bloqueado.
No tiene sentido usar estados de suspensión a un hilo porque este es
estado aplicado a nivel de proceso.
¿Si se expulsa un proceso, todos sus hilos se deben expulsar porque
comparten el espacio de direcciones del proceso?
Las cuatro operaciones asociadas a los hilos son:
• Creación: con un nuevo proceso se crea un hilo. Un hilo puede luego crear
•
•
•
otro hilo dentro del mismo proceso, facilitando argumentos e instrucciones al
nuevo hilo.
Bloqueo: si un hilo necesita esperar por un evento se bloquea (salva
registros de usuario, el CP y punteros de pila). El procesador ejecuta otro hilo
en estado Listo, dentro del mismo proceso o en otro diferente.
Desbloqueo: cuando ocurre el evento por el que se ha bloqueado el hilo
Finalización: al completar el hilo (se libera su registro y pilas)
14
Multihilo – Sincronización de hilos
•
•
•
Los hilos de un proceso comparten el mismo espacio de
direcciones y otros recursos.
Cualquier alteración de un recurso por cualquiera de los hilos,
afecta al entorno del resto de los hilos del mismo proceso.
Es necesario sincronizar las actividades de los hilos para que
no interfieran entre ellos o corrompan estructuras de datos.
–
•
Imagine el caso en que dos hilos intentan añadir simultáneamente, un
elemento a una lista doblemente enlazada. Podría perderse un elemento o la
lista podría acabar malformada.
POSIX: IEEE definió un estándar para los hilos conocido como 1003.1c.
Este paquete se conoce como Pthreads y la mayoría de los sistemas
UNIX aceptan dicho paquete.
–
El estándar define más de 60 llamadas a funciones, que son demasiadas
como para verlas en este libro.
15
Multihilo – POSIX
•
•
•
•
IEEE definió un estándar para los hilos conocido como 1003.1c.
Este paquete se conoce como Pthreads.
La mayoría de los sistemas UNIX aceptan dicho paquete.
El estándar define más de 60 llamadas a funciones, que son
demasiadas como para verlas en este libro.
16
Tipos de implementación de hilos
•
Hilos en espacio de usuario ULT: consiste en ubicar los hilos en
espacio de usuario. En este caso el kernel no conoce la existencia
de dichos hilos, este cree que administra procesos con un solo hilo.
17
Tipos de implementación de hilos
Hilos en espacio de usuario ULT
• Ventajas
–
–
–
•
Un paquete de hilos de nivel usuario puede implementarse en un sistema
operativo que no acepte hilos.
Cada proceso tenga su propio algoritmo de planificación personalizado.
El procedimiento que guarda el estado del hilo y el planificador son sólo
procedimientos locales, por lo que es mucho más eficiente invocarlos que
realizar una llamada al kernel (la planificación de hilos es muy rápida).
Problemas
–
–
–
–
La manera en que se implementan las llamadas al sistema de bloqueo.
Los hilos pueden utilizar llamadas de bloqueo para evitar que un hilo
bloqueado afectara a los demás, pero esto suele generar muchos problemas.
Cambiar esta implementación requiere modificar muchas aplicaciones de
usuario.
Se usa el sistema de envoltura para comprobar posibles bloqueos (es torpe).
18
Tipos de implementación de hilos
Hilos en espacio de usuario ULT
• Problemas
–
–
–
Fallos de página: el ordenador se pueden configurar para que no todo el
programa se encuentre en memoria a la vez. Si el programa llama o salta a
una instrucción que no esté en memoria, ocurre un fallo de página y el sistema
operativo obtiene la instrucción faltante (y las instrucciones aledañas) del
disco.
El proceso se bloquea mientras la instrucción necesaria se localiza y se lee.
Si un hilo produce un fallo de página, el kernel (quien no sabe de la existencia
de los hilos) bloquea naturalmente todo el proceso hasta que se complete la
operación de E/S, incluso si otros hilos pudieran ser ejecutados.
19
Tipos de implementación de hilos
•
Hilos en el kernel KLT: el kernel tiene una tabla de hilos que lleva
la cuenta de todos los hilos en el sistema. Cuando un hilo desea
crear un nuevo hilo o destruir uno existente, realiza una llamada al
kernel, la cual se encarga de la creación o destrucción mediante
una actualización en la tabla de hilos del kernel.
20
Tipos de implementación de hilos
Hilos en el kernel KLT: características
–
–
–
•
Cuando un hilo se bloquea, el kernel puede ejecutar otro hilo del mismo
proceso (si hay otro listo) o un hilo de un proceso distinto.
Los hilos de kernel no requieren de nuevas llamadas al sistema sin bloqueo.
Si un hilo en un proceso produce un fallo de página, el kernel puede
comprobar con facilidad si el proceso tiene otros hilos que puedan ejecutarse y
de ser así, ejecuta uno de ellos mientras espera a que se traiga la página
requerida desde el disco.
Problemas
–
–
–
–
El costo de una llamada al sistema es considerable, por lo que si las
operaciones de hilos son comunes, habrá sobrecarga.
El uso de fork() para crear otro proceso con muchos hilos
Las señales se envían a los procesos, no a los hilos (modelo clásico).
Los hilos de kernel son mejores que los hilos de usuario, pero estos son más
lentos.
21
Recordar: Interrupción
Interrupciones:
–
–
–
–
•
Señal que envía un dispositivo de E/S a la CPU para indicar que la operación
de la que estaba ocupado, ya ha terminado. Las interrupciones son manejadas
por el procesador después de que finaliza la instrucción actual.
Interrupciones por Hardware: el hardware avisa al SO cuando el dispositivo
de E/S ha terminado para que este intervenga y hacer que el programa que
estaba esperando el dispositivo, continúe su ejecución.
Interrupciones por Software: se produce cuando un usuario solicita una
llamada del sistema (a través de un programa).
Ambas permiten al SO utilizar la CPU en otras aplicación, mientras otra
permanece a la espera de que concluya una operación en un dispositivo de
E/S.
Interrupciones TRAP:
–
Estas instrucciones permiten que un programa genere una interrupción. Estas
instrucciones se emplean fundamentalmente para solicitar los servicios del
sistema operativo.
22
Recordar: Interrupción
Interrupciones TRAP:
•
•
•
•
Estas instrucciones permiten que un programa genere una interrupción. Estas
instrucciones se emplean fundamentalmente para solicitar los servicios del SO.
La forma en que se realiza una llamada al sistema consiste en colocar un conjunto
de parámetros en un lugar específico, para después ejecutar una instrucción del
lenguaje máquina del procesador denominada trap (en castellano, trampa).
La ejecución de esta instrucción máquina hace que el hardware guarde el contador
de programa y la palabra de estado del procesador (PSW, Processor Status Word)
en un lugar seguro de la memoria, cargándose un nuevo contador de programa y
una nueva PSW.
Este nuevo contador de programa contiene una dirección de memoria donde reside
una parte (un programa) del SO, el cual se encarga de llevar a cabo el servicio
solicitado. Cuando el sistema operativo finaliza el servicio, coloca un código de
estado en un registro para indicar si hubo éxito o fracaso, y ejecuta una instrucción
return from trap, esta instrucción provoca que el hardware restituya el contador de
programa y la PSW del programa que realizó la llamada al sistema, prosiguiéndose
así su ejecución.
23
Multiprocesamiento simétrico: SMP
Los dos enfoques más populares para proporcionar paralelismo a través de la réplica
de procesadores: multiprocesamiento simétricos (SMP) y clústers.
La arquitectura SMP puede encajar dentro de las categorías de procesamiento
paralelo.
•
•
•
•
SISD
SIMD
MISD
MIMD
24
Multiprocesamiento simétrico: SMP
•
•
•
•
Única instrucción, único flujo de datos – Single instruction single data (SISD)
stream. Un solo procesador ejecuta una única instrucción que opera sobre datos
almacenados en una sola memoria.
Única instrucción, múltiples flujos de datos – Single instruction multiple data
(SIMD) stream. Una única instrucción de máquina controla la ejecución
simultánea de un número de elementos de proceso. Cada elemento de proceso
tiene una memoria de datos asociada, de forma que cada instrucción se ejecuta
en un conjunto de datos diferente a través de los diferentes procesadores. Los
procesadores vectoriales y matriciales entran dentro de esta categoría.
Múltiples instrucciones, único flujo de datos – Multiple instruction single
data (MISD) stream. Se transmite una secuencia de datos a un conjunto de
procesadores, cada uno de los cuales ejecuta una secuencia de instrucciones
diferente. Esta estructura nunca se ha implementado.
Múltiples instrucciones, múltiples flujos de datos – Multiple instruction
multiple data (MIMD) stream. Un conjunto de procesadores ejecuta
simultáneamente diferentes secuencias de instrucciones en diferentes conjuntos
de datos.
25
Multiprocesamiento simétrico: SMP
•
•
•
•
MIMD permite establecer un propósito general para los procesadores, porque
deben ser capaces de procesar todas las instrucciones necesarias para realizar
las transformaciones de datos apropiadas.
MIMD se puede subdividir por la forma en que se comunican los procesadores. Si
cada procesador tiene una memoria dedicada, cada elemento de proceso es en sí
un ordenador. La comunicación entre los computadores se puede realizar a través
de rutas prefijadas o bien a través de redes.
Este sistema es conocido como un cluster, o multicomputador. Si los
procesadores comparten una memoria común, entonces cada procesador accede
a los programas y datos almacenados en la memoria compartida, y los
procesadores se comunican entre sí a través de dicha memoria; este sistema se
conoce como multiprocesador de memoria compartida.
El diseño de SMP y clústers es complejo, e involucra temas relativos a la
organización física, estructuras de interconexión, comunicación entre
procesadores, diseño del sistema operativo y técnicas de aplicaciones software.
26
Organización de un SMP
27
Consideraciones de diseño del SO
•
•
•
•
•
Procesos o hilos simultáneos concurrentes. Las rutinas del núcleo necesitan
ser reentrantes para permitir que varios procesadores ejecuten el mismo código
del núcleo simultáneamente.
Planificación. La planificación se puede realizar por cualquier procesador, por lo
que se deben evitar los conflictos.
Sincronización. Con múltiples procesos activos, que pueden acceder a espacios
de direcciones compartidas o recursos compartidos de E/S, se debe tener cuidado
en proporcionar una sincronización eficaz.
Gestión de memoria. La gestión de memoria en un multiprocesador debe tratar
con todos los aspectos encontrados en las máquinas uniprocesador.
Fiabilidad y tolerancia a fallos. El sistema operativo no se debe degradar en
caso de fallo de un procesador.
28
Micronúcleos
Ventajas
•
•
•
•
•
•
•
Interfaces uniformes.
Extensibilidad
Flexibilidad
Portabilidad
Fiabilidad
Soporte de sistemas distribuidos
Soporte de sistemas operativos
orientados a objetos (OOOS).
29
Micronúcleos
•
•
•
•
•
•
El micronúcleo nos lleva por sí mismo al soporte de sistemas distribuidos,
incluyendo clústeres controlados por sistemas operativos distribuidos.
Cuando se envía un mensaje desde un cliente hasta un proceso servidor, el
mensaje debe incluir un identificador del servicio pedido.
Si se configura un sistema distribuido (por ejemplo, un clúster) de tal forma que
todos los procesos y servicios tengan identificadores únicos, entonces habrá una
sola imagen del sistema a nivel de micronúcleo.
Un proceso puede enviar un mensaje sin saber en qué máquina reside el servicio
pedido.
Una arquitectura micronúcleo funciona bien en el contexto de un sistema operativo
orientado a objetos.
Un enfoque orientado a objetos puede servir para diseñar el micronúcleo y para
desarrollar extensiones modulares para el sistema operativo.
30
Micronúcleos: otros aspectos
•
•
Una potencial desventaja que se cita a menudo de los micronúcleos es la del
rendimiento. Lleva más tiempo construir y enviar un mensaje a través del
micronúcleo.
Gestión de memoria a bajo nivel. El micronúcleo tiene que controlar el concepto
hardware de espacio de direcciones para hacer posible la implementación de
protección a nivel de proceso.
 Conceder (Grant). El propietario de un espacio de
direcciones (un proceso) puede conceder alguna de sus
páginas a otro proceso. El núcleo borra estas páginas del
espacio de memoria del otorgante y se las asigna al proceso
especificado.
 Proyectar (Map). Un proceso puede proyectar cualquiera de
sus páginas en el espacio de direcciones de otro proceso, de
forma que ambos procesos tienen acceso a las páginas. Esto
genera memoria compartida entre dos procesos. El núcleo
mantiene la asignación de estas páginas al propietario inicial,
pero proporciona una asociación que permite el acceso de
otros procesos.
 Limpiar (Flush). Un proceso puede reclamar cualquier
página que fue concedida o asociada a otro proceso.
31
Micronúcleos: otros aspectos
•
•
Comunicación entre procesos (Interprocess Communication). La forma
básica de comunicación entre dos procesos o hilos en un sistema operativo con
micronúcleo son los mensajes.
Gestión de E/S e interrupciones. Con una arquitectura micronúcleo es posible
manejar las interrupciones hardware como mensajes e incluir los puertos de E/S
en los espacios de direcciones.
–
–
El micronúcleo puede reconocer las interrupciones pero no las puede manejar.
Este genera un mensaje para el proceso a nivel de usuario que está actualmente asociado con esa
interrupción.
32
Bibliografía
•
•
•
CARRETERO, Jesús, GARCÍA, Félix, DE MIGUEL, Pedro, PÉREZ,
Fernando. Sistemas Operativos: una visión aplicada. McGraw-Hill, 2001.
STALLINGS, William. Sistemas operativos: aspectos internos y
principios de diseño. 5ª Edición. Editorial Pearson Educación. 2005.
ISBN: 978-84-205-4462-5.
TANENBAUM, Andrew S. Sistemas operativos modernos. 3ª Edición.
Editorial Prentice Hall. 2009. ISBN: 978-607- 442-046-3.
33
marlon.cardenas@ufv.es
Grado en Ingeniería Informática
Escuela Politécnica Superior
Tema
3.2
Sistema Operativos
(SSOO)
Gestión de Hilos y SMP
Grado en Ingeniería Informática
Escuela Politécnica Superior
Índice
•
Gestión de Hilos y SMP
 Windows
 Linux
2
Gestión de hilos: Windows
•
Las estructuras de los procesos y los servicios
proporcionados por el núcleo de Windows son
relativamente sencillos y de propósito general.
–
–
–
•
•
Los procesos Windows están implementados como objetos.
Un proceso ejecutable puede contener uno o más hilos.
Tanto el objeto proceso como el objeto hilo, tienen
funcionalidades de sincronización preconstruidas.
Cuando Windows crea un nuevo proceso, utiliza el objeto
definido para el proceso Windows como plantilla para
generar la nueva instancia del proceso.
En el momento de la creación se asignan los valores de los
atributos.
3
Gestión de hilos: Windows
•
Un proceso Windows debe contener por lo menos un hilo
que ejecutar.
–
–
•
El contexto es un atributo que permita al hilo suspender y
reanudar su ejecución.
–
•
Ese hilo puede a su vez crear otros hilos.
¿En un sistema multiprocesador, múltiples hilos de un mismo
proceso pueden ejecutar en paralelo?
Es posible cambiar el comportamiento de un hilo, alterando su
contenido cuando el hilo está suspendido.
Windows soporta la concurrencia entre procesos ya que
hilos de diferentes procesos pueden ejecutar en paralelo.
–
Múltiples hilos del mismo proceso pueden estar asignados a
distintos procesadores y pueden ejecutar de modo concurrente.
4
Gestión de hilos: Windows
•
•
•
Los hilos del mismo proceso pueden intercambiar información a través
de su espacio de direcciones común.
Estos tienen acceso a los recursos compartidos del proceso.
Los hilos de diferentes procesos pueden intercambiar información a
través del uso de memoria compartida.
5
Gestión de hilos: Windows
6
Gestión de hilos: Windows
7
Gestión de hilos: Windows
8
Gestión de hilos: Windows
9
Gestión de hilos: Windows
•
•
•
Listo (ready): el activador del micronúcleo conoce todos los hilos listos
y los planifica en orden de prioridad.
Substituto (standby): un hilo substituto se ha seleccionado para
ejecutar en siguiente lugar en un determinado procesador. Si la
prioridad del hilo substituto es suficientemente alta, el hilo actualmente
en ejecución en ese procesador podría ser expulsado en su favor. De
otra forma, el hilo substituto espera hasta que el hilo en ejecución se
bloquea o finaliza su porción de tiempo.
Ejecutando (running): una vez que el micronúcleo realiza un
intercambio de hilo o proceso, el hilo sustituto pasa al estado de
ejecución y ejecuta hasta que es expulsado, finaliza su porción de
tiempo, se bloquea o termina. En los dos primeros casos vuelve a la
cola de listos.
10
Gestión de hilos: Windows
•
•
•
Esperando (waiting): un hilo pasa a estado esperando cuando (1) se
bloquea en un evento (por ejemplo, E/S), (2) espera voluntariamente
por temas de sincronización, o (3) un subsistema manda al hilo a
estado de suspendido. Cuando se satisface la condición de espera, el
hilo pasa al estado Listo si todos sus recursos están disponibles.
Transición (transition): un hilo entra en este estado después de
esperar si está listo para ejecutar pero los recursos no están
disponibles. Por ejemplo, la pila del hilo puede no estar en memoria.
Cuando los recursos están disponibles, el hilo pasa al estado Listo.
Terminado (terminated): un hilo se puede finalizar por sí mismo, por
otro hilo o cuando su proceso padre finaliza. Cuando se completan las
tareas internas, el hilo se borra del sistema, o puede retenerse por el
ejecutivo para futuros reinicios.
11
Gestión de hilos: Solaris
Solaris utiliza cuatro conceptos relacionados con los hilos:
• Procesos: es un proceso normal UNIX e incluye el espacio de
direcciones del usuario, la pila y el bloque de control del proceso.
• Hilos de nivel de usuario: implementados a través de una biblioteca
de hilos en el espacio de direcciones de un proceso, son invisibles al
sistema operativo. Los hilos de nivel de usuario (user-level threads,
ULT) son la interfaz para las aplicaciones paralelas.
• Procesos ligeros: un proceso ligero (light-weight process, LWP)
puede ser visto como una asociación entre ULT e hilos de núcleo.
Cada LWP soporta uno o más ULT y se asocia con un hilo de núcleo.
Los LWP se planifican de forma independiente por el núcleo y pueden
ejecutar en paralelo en múltiples procesadores.
• Hilos de núcleo: son entidades fundamentales que se pueden
planificar para ejecutar en cualquier procesador del sistema.
12
Gestión de hilos: Solaris
Solaris utiliza cuatro conceptos relacionados con los hilos:
• Procesos: es un proceso normal UNIX e incluye el espacio de
direcciones del usuario, la pila y el bloque de control del proceso.
• Hilos de nivel de usuario: implementados a través de una biblioteca
de hilos en el espacio de direcciones de un proceso, son invisibles al
sistema operativo. Los hilos de nivel de usuario (user-level threads,
ULT) son la interfaz para las aplicaciones paralelas.
• Procesos ligeros: un proceso ligero (light-weight process, LWP)
puede ser visto como una asociación entre ULT e hilos de núcleo.
Cada LWP soporta uno o más ULT y se asocia con un hilo de núcleo.
Los LWP se planifican de forma independiente por el núcleo y pueden
ejecutar en paralelo en múltiples procesadores.
• Hilos de núcleo: son entidades fundamentales que se pueden
planificar para ejecutar en cualquier procesador del sistema.
13
Gestión de hilos: Unix vs. Solaris
14
Bibliografía
•
•
•
CARRETERO, Jesús, GARCÍA, Félix, DE MIGUEL, Pedro, PÉREZ,
Fernando. Sistemas Operativos: una visión aplicada. McGraw-Hill, 2001.
STALLINGS, William. Sistemas operativos: aspectos internos y
principios de diseño. 5ª Edición. Editorial Pearson Educación. 2005.
ISBN: 978-84-205-4462-5.
TANENBAUM, Andrew S. Sistemas operativos modernos. 3ª Edición.
Editorial Prentice Hall. 2009. ISBN: 978-607- 442-046-3.
15
marlon.cardenas@ufv.es
Grado en Ingeniería Informática
Escuela Politécnica Superior
Tema
3.3
Sistema Operativos
(SSOO)
Procesos e Hilos en C
Grado en Ingeniería Informática
Escuela Politécnica Superior
Índice
•
Gestión de Hilos y Procesos
 Crear procesos con fork()
 Ejecutar procesos con exec
2
Procesos e Hilos: diferencias
Si se quiere que una aplicación ejecute tareas en paralelo
existen dos opciones:
• Crear un nuevo proceso
• Crear un nuevo hilo (thread)
Procesos
• Un proceso de Unix es cualquier programa en ejecución, el
cual es totalmente independiente de otros procesos.
• Un proceso no se puede meter en la zona de memoria de otro
proceso.
• En un proceso puede haber varios hilos de ejecución.
• Un proceso es más costoso de lanzar, necesita crear una
copia de todo su contenido en memoria.
3
Procesos e Hilos: diferencias
Hilos
• Dentro de un proceso todos los hilos comparten la misma
memoria.
• Si un hilo modifica una variable, los demás hilos del mismo
proceso verán dicha modificación.
• Lo anterior hace necesario el uso de semáforos o mutex
(EXclusión MUTua en español) para evitar que dos hilos
modifiquen a la vez a la misma estructura de datos.
• Si un hilo “corrompe" una zona de memoria, los otros hilos del
mismo proceso verán la memoria estropeada.
• Un fallo en un hilo puede hacer fallar a todos los hilos del
mismo proceso.
4
Procesos e Hilos: diferencias
Importante
•
•
•
En los hilos, al compartir la memoria y los recursos, es necesario el
uso de mutex o semáforos, haciendo compleja su programación.
Cuando se lanza un proceso, este se hace independiente de quien
lo lanzó, evitando así problemas de memoria.
Si se necesita que haya comunicación entre procesos, será
necesario pensar en el uso de memorias compartidas y sus
semáforos, el uso de colas de mensaje, sockets o cualquier otro
mecanismo de comunicación entre procesos en Unix.
¿Cuándo uso procesos y cuándo uso hilos?
-
Procesos: cuando hay poca comunicación entre ellos.
Hilos: cuando es necesario compartir, cuando hay que actualizar
datos o cuando se necesitan muchos cálculos en paralelo.
5
Procesos e Hilos: fork()
•
fork(), en el punto donde se llame, duplica los procesos y
estos empiezan a ejecutarse por separado.
–
•
•
El retorno de dicha función es, al proceso original, un identificador del
proceso nuevo.
Al proceso nuevo le devuelve 0.
–
Cada proceso puede saber si es el original o el proceso padre o el
proceso nuevo (proceso hijo), de esta forma cada uno puede hacer
cosas distintas.
Un fork() en un if, permite que el proceso padre siga por la
parte del else y proceso hijo por el then.
–
–
El proceso original podría seguir atendiendo nuevos clientes que
quieran conectarse a nuestro programa por un socket.
El proceso hijo podrá atender a un cliente que acaba de conectarse y
que es el que ha provocado que lancemos el fork().
6
Procesos e Hilos: fork()
•
•
•
•
•
Recuerde que fork duplica todo el espacio de memoria. Por ello,
ambos procesos tienen todas las variables repetidas, pero
distintas.
Si el proceso padre modifica la variable “counter", el proceso hijo
no verá reflejado el cambio en su versión de “counter".
Si antes del fork(), por ejemplo, se tiene un fichero abierto (un
fichero normal, un socket o cualquier otra cosa), después del
fork() ambos procesos tendrán abierto el mismo fichero y ambos
podrán escribir en él.
Uno de los procesos puede cerrar el fichero mientras que el otro lo
puede seguir teniendo abierto.
fork() puede devolver -1 en caso de error. Si esto ocurre, no se ha
creado ningún nuevo proceso.
7
Procesos e Hilos: fork()
•
•
•
•
•
El proceso padre puede "esperar"
que el hijo termine.
La función wait() permite “pausar” un
proceso.
wait() recibe como parámetro la
dirección de un entero para que nos
lo devuelva relleno.
La función wait() deja dormido al
proceso que la llama hasta que
alguno de sus procesos hijo termina.
En el entero se guardará la
información de cómo ha terminado el
hijo: llamando a exit(), recibe kill,
está caido, otro…).
8
Procesos e Hilos: pthread_create
•
•
WIFEXITED(estadoHijo)
–
–
Es 0 si el hijo ha terminado de una manera anormal (caída, con un kill, etc).
Distinto de 0 si ha terminado porque ha hecho una llamada a la función exit()
WEXITSTATUS(estadoHijo)
–
Devuelve el valor que ha pasado el hijo a la función exit(), siempre y cuando
la macro anterior indique que la salida ha sido por una llamada a exit().
9
Procesos e Hilos: pthread_create
Parámetros de pthread_create() :
• pthread_t * puntero a un identificador de thread. La función devuelve
este valor relleno con lo que luego posible hacer referencia al hilo.
• pthread_attr_t * atributos de creación del hilo. Hay varios atributos
posibles, como por ejemplo la prioridad. Un hilo de mayor prioridad se
ejecutará con preferencia (tendrá más rodajas de tiempo) que otros
hilos de menor prioridad. Si pasa NULL el hilo se creará con sus
atributos por defecto. Si necesita un programa que cree y destruya
hilos continuamente, evite el uso de NULL debido a que podría dejar
memoria sin liberar al terminar un hilo.
• void *(*)(void *) es el tipo de una función que admite un puntero void
* y que devuelve void *. Eso quiere decir que a este parámetro le
podemos pasar el nombre de una función que cumpla lo antes dicho.
10
Procesos e Hilos: pthread_create
Parámetros de pthread_create() :
• void *(*)(void *) esta función es la que se ejecutará como un hilo
aparte. El hilo terminará cuando la función termine o cuando llame a
la función pthread_exit(). Es común hacer que esta función cree un
bucle infinito y quede suspendido en un semáforo o a la espera de
una señal para hacer lo que tenga que hacer (luego volver a quedar
dormido).
• void * es el parámetro que se le pasará a la función anterior cuando
se ejecute en el hilo aparte. El programa principal puede pasar un
único parámetro a la función que se ejecutará en el hilo. La función
del hilo sólo tendrá que hacer el "cast" adecuado.
11
Llamadas exec
UNIX dispone de exec para lanzar a ejecución un programa,
almacenado en forma de fichero.
Sólo existe una llamada pero las bibliotecas estándares de C
disponen de varias funciones, todas comenzando por 'exec'
que se diferencian por el tipo de parámetros que se pasan al
programa.
• execl: es la forma simple y se usa cuando se conoce a
priori el número de argumentos.
–
–
int execl ( char* file, char* arg0, char* arg1, ... , 0 );
file: nombre del fichero seguido de todos los argumentos, al final un
puntero nulo o con valor cero.
–
Ejemplo, ejecute la siguiente instrucción: /bin/ls -l /usr/include
12
Llamadas exec
•
Utilice: execl ( "/bin/ls", "ls", "-l", "/usr/include", 0 );
–
•
Sino conoce de ante mano el número de argumentos, se
emplea la función execv:
–
•
Argumentos: nombre del programa, comando, parámetros,
contexto, puntero nulo.
execv ( char* fichero, char* argv [] );
El parámetro argv es una lista que representa los
argumentos del programa. El útlimo valor de la lista es un
nulo o cero. Adaptamos el ejemplo anterior:
–
–
char* agurments [] = { "ls", "-l", "/usr/include", 0 };
execv ( "/bin/ls", agurments );
13
Llamadas exec
•
Hasta ahora se ha escrito el nombre completo del fichero o
comando a ejecutar "/bin/ls" en vez de "ls".
–
•
•
•
En este caso, tanto execl como execv no tienen en cuenta la
variable PATH.
– Para tener en cuenta esta variable, utilice las versiones execlp o
execvp.
– execvp ( "ls", arguments );
– El programa "/bin/ls“ se ejecutará si "/bin" está definida en el PATH.
Retorno de exec: todas las llamadas exec retornan un valor diferente
de NULL si el programa no se ha podido ejecutar.
En caso de que sí se ejecute el programa, se transfiere el control a éste
y la llamada exec nunca retorna.
En cierta forma el programa que invoca un exec desaparece del mapa.
14
Sección crítica: sección de código dentro de un proceso que requiere acceso a recursos
(critical section) compartidos y que no puede ser ejecutada mientras otro proceso esté en
una sección de código correspondiente.
Interbloqueo: situación en la cual dos o más procesos son incapaces de actuar porque
(deadlock) cada uno está esperando que alguno de los otros haga algo.
Círculo vicioso: situación en la cual dos o más procesos cambian continuamente su
estado (livelock) en respuesta a cambios en los otros procesos, sin realizar ningún
trabajo útil.
exclusión mutua: requisito de que cuando un proceso esté en una sección crítica que
accede a recursos compartidos, ningún otro proceso pueda estar en una sección crítica
que acceda a ninguno de esos recursos compartidos.
condición de carrera: situación en la cual múltiples hilos o procesos leen y escriben un
dato (race condition) compartido y el resultado final depende de la coordinación relativa
de sus ejecuciones.
Inanición: situación en la cual un proceso preparado para avanzar es soslayado
(starvation) indefinidamente por el planificador; aunque es capaz de avanzar, nunca se le
escoge.
15
Bibliografía
•
•
•
CARRETERO, Jesús, GARCÍA, Félix, DE MIGUEL, Pedro, PÉREZ,
Fernando. Sistemas Operativos: una visión aplicada. McGraw-Hill, 2001.
STALLINGS, William. Sistemas operativos: aspectos internos y
principios de diseño. 5ª Edición. Editorial Pearson Educación. 2005.
ISBN: 978-84-205-4462-5.
TANENBAUM, Andrew S. Sistemas operativos modernos. 3ª Edición.
Editorial Prentice Hall. 2009. ISBN: 978-607- 442-046-3.
16
marlon.cardenas@ufv.es
Grado en Ingeniería Informática
Escuela Politécnica Superior
Sistemas
Operativos II
TEMA 4.1
Sincronización y
comunicación
4.1.1 PROBLEMAS DE SINCRONIZACIÓN
Y COMUNICACIÓN ENTRE PROCESOS
Sincronización y Comunicación
Concurrencia: ejecución asíncrona de varios procesos con acceso a los mismos recursos.
La concurrencia de procesos puede representarse en tres contextos diferentes:
1. Varias aplicaciones ejecutándose a la vez sobre el mismo procesador.
2. Aplicaciones implementadas como conjuntos de procesos concurrentes.
3. Estructuración de los SSOO como conjunto de procesos concurrentes.
En un sistema donde está permitida la ejecución concurrente de procesos se debe garantizar la
existencia de:
●
Mecanismos de acceso exclusivo a los recursos compartidos.
●
Mecanismos de sincronización y comunicación que permitan establecer un orden de
ejecución en los procesos.
Sincronización y Comunicación
Ejemplo: E/S por teclado y pantalla.
static char sal, ent;
(1)
void echo() {
extern char sal,ent;
getc(ent);
sal := ent;
puts(sal);
} // echo
void main () {
...
echo();
...
} // main
P1 y P2 ejecutan a la vez este código
1. P1 ejecuta main, llega a la llamada a echo y ejecuta
hasta (1) cargando x en ent.
2. P2 ejecuta todo el código hasta el final, cargando y, y
mostrandola por pantalla.
3. P1 termina su ejecución, muestra y.
Sincronización y Comunicación
Ejemplo: (continúa)
Para solucionar la ejecución errónea se puede plantear el siguiente requisito:
●
echo() es una función global pero sólo lo puede utilizar un proceso a la vez. La
secuencia de ejecución sería la siguiente:
●
P1 llama a echo() y es interrumpido justo después de llamar a la función de entrada, en (1).
●
P2 llama a echo() pero no puede utilizarlo porque está bloqueado (está siendo usado por
otro proceso), por lo que se detiene P2 hasta que pueda acceder a echo().
●
P1 retoma la ejecución y completa echo().
●
P2 puede ahora ejecutar echo() sin cometer ningún error.
Conclusión: los recursos globales deben estar protegidos para evitar errores.
En sistemas multiprocesador el problema es similar: varios procesos ejecutando a la vez
pueden realizar accesos simultáneos a recursos.
Sincronización y Comunicación
Funciones de Gestión del SO relacionadas con Concurrencia:
●
Seguir la pista de los procesos activos: control de PCBs.
●
Asignar y retirar recursos a los procesos en función de:
●
●
●
Tiempo de procesador (planificación)
●
Memoria consumida (gestión de memoria virtual)
●
Utilización de archivos
●
Utilización de recursos de E/S
Protección de datos y recursos asignados a cada proceso.
Los resultados de un proceso deben ser independientes de su velocidad de ejecución. No
se deben ver afectados por interrupciones en la propia ejecución de un proceso.
4.1.2 EXCLUSIÓN MUTUA.
SOPORTES.
Exclusión Mutua
Requisitos para la exclusión mutua:
●
●
●
●
Debe cumplirse la exclusión mutua, es decir, debe permitirse a los procesos acaparar el
uso de recursos críticos con exclusividad.
Dos procesos no pueden estar simultáneamente en sus secciones críticas.
No se pueden hacer suposiciones acerca de la velocidad de ejecución de los procesos o
cantidad de ellos en ejecución.
Cuando ningún proceso está en la sección crítica, cualquier proceso que lo solicite debe
poder entrar en ella.
●
Ningún proceso esperará indefinidamente para entrar en sección crítica.
●
Los procesos solo pueden estar en la sección crítica durante un periodo finito de tiempo.
●
Ningún proceso que se ejecute fuera de su región crítica puede bloquear a otros procesos.
Estos requisitos pueden ser implementados bien por SW, bien por HW.
Soporte SW para Exclusión Mutua
Todas las soluciones SW suponen la existencia de unas primitivas HW para la exclusión
mutua en el acceso a memoria.
Primer intento: solución por turnos.
●
Protocolo del Iglú: “vivienda unipersonal con una pizarra dentro, por cuya puerta solo
cabe una persona”.
●
Los procesos del sistema se asemejan a los esquimales de este protocolo.
●
En la pizarra estará escrito el proceso cuyo turno está activo.
●
●
Si un proceso “entra” y “ve” su turno → ejecuta su sección crítica y después cambia el
turno.
Si un proceso “entra” y NO está su turno → se sale y espera, luego vuelve a entrar para
comprobar si ya es su turno.
Soporte SW para Exclusión Mutua
Primer intento: solución por turnos.
La implementación, considerando a turno:0..1 variable compartida sería:
Garantiza exclusión mutua.
Inconvenientes:
●
Los procesos deben alternar estrictamente sus secciones críticas.
●
Si uno de los procesos falla, el otro puede quedarse esperando indefinidamente para entrar
en la sección crítica.
●
Problema de la solución: sólo considera el estado de uno de los procesos a la hora de
entrar en la sección crítica. Debería considerar el de los dos.
Soporte SW para Exclusión Mutua
Segundo intento: variables cerrojo.
●
●
Cada esquimal tiene su propio iglú en el que puede leer y escribir, pero en el iglú del
prójimo sólo puede leer.
A la hora de entrar en la sección crítica, el proceso “mira” la pizarra del otro para ver si
está a FALSE. Si es así,
●
Escribe en su pizarra TRUE para que el otro sepa que está en su sección crítica.
●
Ejecuta su sección crítica.
●
Escribe FALSE en su pizarra.
Implementación considerando int senial[2] las “pizarras” compartidas:
Soporte SW para Exclusión Mutua
Segundo intento: variables cerrojo.
Esta solución garantiza:
●
Que cada proceso puede entrar en su sección crítica todas las veces que lo desee,
independientemente de lo que el otro haga.
●
Si uno de ambos procesos falla fuera de su sección crítica, el otro todavía puede seguir
ejecutándose.
Inconvenientes:
No garantiza totalmente la exclusión mutua. Ejemplo:
●
P0 ejecuta la sentencia while y encuentra senial[1] == 0.
●
P1 ejecuta la sentencia while y encuentra senial[0] == 0.
●
P0 pone senial[0] = 1 y entra en su sección crítica.
●
P1 pone senial[1] = 1 y entra en su sección crítica.
¡ Los dos procesos están a la vez en sus secciones críticas !
La solución no es independiente de la velocidad relativa de ejecución de los procesos.
Soporte SW para Exclusión Mutua
Tercer intento:
El problema de la propuesta anterior radica en que los procesos pueden cambiar su estado
después de que el otro proceso lo haya comprobado. Solución:
Esta solución garantiza:
●
Exclusión mutua.
●
●
Cada proceso puede entrar en su sección crítica todas las veces que lo desee,
independientemente de lo que el otro haga.
Si uno de los procesos falla fuera de su sección crítica, el otro todavía puede seguir
ejecutándose.
Soporte SW para Exclusión Mutua
Tercer intento:
Inconvenientes:
●
Se puede dar interbloqueo. Por ejemplo, en la siguiente situación:
●
P0 pone senial[0] = 1
●
P1 pone senial[1] = 1
●
Ninguno de los dos puede entrar en su sección crítica y como consecuencia, ambos
esperarán indefinidamente a que el otro cambie el valor de las variables cerrojo.
Los procesos cambian su estado antes de conocer el estado del otro.
Sin embargo, el problema de este intento es que cada proceso fija su estado sin tener en
cuenta el estado del otro proceso.
Solución: “lecciones de educación”
Soporte SW para Exclusión Mutua
Cuarto intento:
Los procesos, tras recibir “lecciones de educación” actúan así:
1.Activan su señal.
2.Se preparan para desactivar su señal y “ceder el paso” al otro proceso.
●
●
Garantiza exclusión mutua.
Gran retraso en llegar a la solución, sin llegar al interbloqueo.
Soporte SW para Exclusión Mutua
Cuarto intento:
Ejemplo de secuencia de ejecución:
1. P0: senial[0] = 1
2. P1: senial[1] = 1
3.P0 comprueba senial[1], que es 1, y por tanto entra en el bucle.
4.P1 comprueba senial[0], que es 1, y por tanto entra en el bucle.
5.P0: senial[0]
6.P1: senial[1]
7.P0: senial[0]
8. P1: senial[1]
=
=
=
=
0
0
1
1
(primera instrucción del bucle de espera)
(primera instrucción del bucle de espera)
(última instrucción del bucle de espera)
(última instrucción del bucle de espera)
9. Vuelta al paso 3
●
Retraso en llegar a la solución hasta que alguno de los procesos realice el cambio a 0 de
su señal antes de que el otro compruebe su valor.
Soporte SW para Exclusión Mutua
Algoritmo de Dekker:
●
●
Diseñado por Dijkstra en 1965 para solucionar el problema de acceso en exclusión mutua
planteado por el matemático holandés Dekker.
Suma a la observación del estado de los procesos la inclusión de un turno.
Soporte SW para Exclusión Mutua
Algoritmo de Dekker:
Esta solución garantiza:
●
Exclusión mutua.
●
●
●
Cada proceso puede entrar en su sección crítica todas las veces que lo desee, mientras
que el otro no muestre intención de entrar en su sección crítica (a través de senial).
Si uno de los procesos falla fuera de su sección crítica, el otro todavía puede seguir
ejecutándose porque el que falló puso su senial a 0 justo al salir de la sección crítica.
No existe interbloqueo gracias a la variable compartida turno.
Inconvenientes:
●
Demasiado complejo para demostrar su corrección en cualquier caso.
●
Difícilmente extensible a n procesos.
Soporte SW para Exclusión Mutua
Algoritmo de Peterson:
Simplificación del algoritmo de Dekker. Utiliza las variables de estado y turno.
Estudio de casos: supongamos P0 bloqueado en while. P0 sólo puede entrar cuando una de
las dos condiciones deje de cumplirse:
●
●
●
P1 no está interesado en entrar en su SC: imposible porque senial[1] == 1.
P1 está esperando a entrar en su SC: imposible porque si turno == 1, P1 puede entrar en su SC.
P1 monopoliza SC: no puede ocurrir porque P1 pone turno = 0 antes de la SC.
El algoritmo de Peterson es fácilmente generalizable para n procesos
Soporte HW para Exclusión Mutua
Inhabilitar Interrupciones:
●
●
El SO, a través de las interrupciones, toma el control y cambia el proceso en ejecución.
Se puede resolver la exclusión mutua haciendo que un proceso que vaya a ejecutar su
sección crítica deshabilite las interrupciones para que nada le detenga, restaurándolas
una vez que terminó su sección crítica. Implementación:
repeat
<inhabilitar interrupciones>
<sección crítica>
<habilitar interrupciones>
...
forever
●
●
Ventaja: garantiza exclusión mutua.
Inconvenientes: pérdida de rendimiento (disminuye el grado de multiprogramación), no
soluciona el problema en sistemas multiprocesador.
Soporte HW para Exclusión Mutua
Instrucciones Máquina Especiales:
●
●
●
●
●
●
●
●
Problemas de soluciones SW:
Necesario utilizar dos instrucciones para leer y escribir .
Necesario utilizar dos instrucciones para leer e intercambiar valores en las variables
cerrojo.
Todas las soluciones SW suponen la existencia de unas primitivas HW para la exclusión
mutua en el acceso a memoria.
Solución: proponer instrucciones máquina atómicas para estas operaciones.
Estas instrucciones se ejecutan “en un ciclo de reloj”.
Implementadas en ensamblador como atómicas.
En este curso estudiaremos Test and Set e Intercambiar
Soporte HW para Exclusión Mutua
Test and Set:
Definición:
int TestAndSet (int *i) {
if (*i == 0) {
*i = 1;
return (1);
} else {
return (0);
}
} // TestAndSet
Si el valor de la variable compartida es 0,
la pone a 1 para indicar que se entra en
sección crítica y devuelve 1 (TRUE).
Si el valor de la variable compartida es 1
significa que alguien está en sección crítica,
así que TS devuelve 0 (FALSE).
Solución al problema de exclusión mutua con Test and Set :
Soporte HW para Exclusión Mutua
Intercambiar:
Definición:
void Intercambiar (int *r, int *m) {
int temp;
temp = *m;
*m = *r;
*r = temp;
} // Intercambiar
Solución al problema de ex. mutua:
Inicialmente cerrojo = 0.
El único proceso que puede
ejecutar la sección crítica es
aquel que encuentre cerrojo
a 0.
Idealmente: intercambio de valores
entre un registro (r) y una posición
de memoria (m).
Implementación en “un ciclo”.
Soporte HW para Exclusión Mutua
Ventajas de las soluciones HW:
●
●
●
Se pueden aplicar a cualquier número de procesos en sistemas con memoria compartida,
sean mono o multiprocesador.
Simples y fáciles de verificar.
Se pueden usar para definir varias secciones críticas.
Desventajas de las soluciones HW:
●
●
●
Se emplea espera activa, consumiendo tiempo de procesador.
Puede producirse inanición, porque la selección del proceso a entrar en ejecución es
arbitraria.
Puede producirse interbloqueo. Ejemplo: sistema basado en prioridades.
●
●
●
P0 entra en la sección crítica y pone cerrojo = 1
P1, con mayor prioridad que P0, le interrumpe e intenta entrar en la SC.
P1 se mantiene en espera activa debido a que P0 jamás podrá interrumpirle (tiene menos
prioridad) y desbloquear la variable cerrojo.
4.1.3 SEMÁFOROS.
Semáforos
●
●
●
●
●
●
●
Herramienta SW que permite resolver el problema de la sincronización entre
procesos evitando la espera activa.
Inventados por Dijkstra. Ideas desarrolladas:
Dos o más procesos cooperan y se sincronizan por medio de señales.
Posibilidad de forzar a un proceso a detenerse en una posición concreta hasta que reciba una
determinada señal.
Un semáforo S contendrá una variable entera a la que, una vez asignado un valor
inicial, sólo podrá accederse a través de operaciones atómicas (primitivas) estándar:
wait y signal.
wait(s): permite detener un proceso hasta la llegada de una señal. Decrementa el valor del
semáforo. Si s < 0 el proceso que invoca wait se bloquea.
signal(s): envía una señal al semáforo. Incrementa el valor del semáforo. Si s <= 0 tras
ese incremento, significa que habrá algún proceso bloqueado, de modo que se desbloqueará
al primer proceso bloqueado.
Semáforos
Definición formal de las primitivas de los semáforos:
•
●
Implementación:
struct semaforo {
int contador;
struct cola *buffer_proc;
}
●
Inicialización:
struct semaforo semaf;
semaf.contador = 1;
// Un wait antes de bloqueo
Un semáforo puede inicializarse
a un valor no negativo
Primitiva wait:
void wait(semaf) {
semaf.contador--;
if (semaf.contador < 0) {
semaf.cola.input(proc);
// Coloca en la cola de procesos al que invocó wait.
bloquear();
// El proceso que invocó wait es bloqueado.
}
}
Semáforos
Definición formal de las primitivas de los semáforos (sigue):
Primitiva signal:
void signal(semaf) {
semaf.contador++;
if (semaf.contador <= 0) {
// Algún proceso bloqueado
proc = semaf.cola.primero(); // Se saca al primero
desbloquear(proc);
}
}
Más características:
●
●
●
●
Los procesos en espera se gestionan mediante una FIFO: equitatividad.
Los procesos no pueden permanecer indefinidamente en la cola del semáforo.
Semáforo binario (ó mutex) es aquel cuyo contador solo toma los valores 0 y 1. Los
semáforos binarios son equipotentes a los generales.
Proporcionan una solución al problema de exclusión mutua para n procesos.
Semáforos y exclusion mutua
void main() {
semaforo semaf;
Solución para dos procesos
// Inicialización
semaf.contador = 1;
entero = 0;
// Segmento de memoria compartida (variable)
pid_t pid = fork();
// Creación de proceso hijo
switch(pid) {
case –1: printf(“Error, no funcionó fork”); break;
case 0: P(); break;
// Código del hijo.
default: P(); break;
// Código del padre.
} // switch
} // main
void P() {
while(1) {
wait(semaf);
entero++;
printf(“%i”, entero);
signal(semaf);
} // while
} // P
//// Zona de exclusión mutua ////
//// Zona de exclusión mutua ////
Implementación de Semáforos
●
●
●
Las primitivas wait y signal deben implementarse como operaciones atómicas.
Posibilidades:
Soluciones SW: Algoritmo de Dekker, Algoritmo de Peterson
Soluciones HW: Inhabilitación de interrupciones (preferida), Instrucciones especiales: Test
and Set, Intercambiar
Soporte en lenguajes de programación:
●
●
●
●
C: librerías sem.h, ipc.h
C++: varias implementaciones de clases para sincronizar hebras
Dependientes del SO.
Independientes del SO: ZThreads
http://zthread.sourceforge.net/html/classZThread_1_1Semaphore.html
●
JAVA: clase Semaphore (Java 2, SE 5.0)
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Semaphore.html
Productor / Consumidor - Semáforos
Enunciado:
●
Uno o más procesos productores generan datos de un cierto tipo y los sitúan en un buffer.
●
Uno o varios consumidores sacan los elementos del buffer de uno en uno.
●
Supóngase un buffer ilimitado:
sal
ent
Buffer Ilimitado
Situaciones “delicadas”:
●
Dos productores tratan de acceder al buffer a la vez.
●
Dos consumidores tratan de acceder al buffer a la vez.
●
Un consumidor accede a la vez que un productor...
Productor / Consumidor - Semáforos
Solución 0: sin sincronización
// Compartidas
int buffer[INF];
int ent = 0;
int sal = 0;
// Productor
int v;
while (1) {
v = Produce();
buffer[ent] = v;
ent = ent + 1;
}
sal
ent
// Consumidor
int w;
while (1) {
while (ent <= sal) { /* nada */ };
w = buffer[sal];
sal = sal + 1;
consume(w);
}
Las coincidencias en acceso no están resueltas
buffer
Espera Activa
Productor / Consumidor - Semáforos
Solución 1: semáforos binarios
●
Se gestiona el total de elementos en una variable n para llevar la cuenta del número de
elementos que hay en el buffer:
n = ent - sal
●
●
●
Se utiliza el semáforo binario exmut para hacer cumplir la exclusión mutua sobre n.
Se utiliza el semáforo binario retraso para que el consumidor espere la llegada de
elementos al buffer (esperará si el buffer está vacío).
Suponemos que al menos un productor se ejecutará antes que todos los consumidores. Sin
esta suposición, un consumidor podría extraer elementos de un buffer vacío.
Productor / Consumidor - Semáforos
Solución 1: semáforos binarios
#define numProd 10;
#define numCons 10;
// 10 productores
// 10 consumidores
// Variables compartidas
int n = 0;
semaforo exmut;
semaforo retraso;
// Elementos del buffer
// Ex. mutua
// Evita consumir si buffer vacío
void productor() {
int elemento;
while(1) {
elemento = producir();
//-- Inicio de Sección Crítica.
waitB(exmut);
aniadir(elemento); // Añade elemento al buffer.
n += 1;
if (n == 1)
// El único elemento lo acabamos de
signalB(retraso); // añadir, despierta 1er. bloqueado
signalB(exmut);
//----- Fin de Sección Crítica.
}
}
Productor / Consumidor - Semáforos
Solución 1: semáforos binarios
void consumidor() {
int elemento;
while(1) {
//----- Inicio de Sección Crítica.
waitB(exmut);
// Saca elemento del buffer.
elemento = extraer();
n -= 1;
//----- Fin de Sección Crítica.
signalB(exmut);
consumir(elemento);
// Si se consume último elemento
if (n == 0)
// hay que notificar al semáforo.
waitB(retraso);
}
}
void main() {
exmut.contador = 1;
retraso.contador = 0;
for (int i = 1; i <= numProd; i++) crearProductor();
for (int j = 1; j <= numCons; j++) crearConsumidor();
}
Productor / Consumidor - Semáforos
Solución 1: semáforos binarios
Problemas. Supóngase la siguiente secuencia de ejecución:
(*) Consumidor1 se queda tras la instrucción “if (n==0)”, sin ejecutar la siguiente. Como no está en
sección crítica en ese momento, otro proceso puede ejecutar código de su sección crítica.
Productor / Consumidor - Semáforos
Solución 2: semáforos generales
El semáforo entero n llevará la cuenta de los elementos del buffer.
El semáforo binario exmut servirá para acceder en exclusión mutua al buffer.
// Variables compartidas:
semaforo n;
semaforo exmut;
n.contador = 0;
exmut.contador = 1;
void productor() {
int elemento;
while(1) {
elemento = producir();
waitB(exmut);
aniadir(elemento);
signalB(exmut);
signal(n);
}
}
Solución correcta
void consumidor() {
int elemento;
while(1) {
wait(n);
waitB(exmut);
elemento = extraer();
signalB(exmut);
consumir(elemento);
}
}
Problema de la Barbería - Semáforos
Enunciado (Libro Stallings):
La barbería tiene 3 sillas de peluquería, 3 barberos, una zona de espera donde se pueden
acomodar 4 clientes en un sofá, y una sala de espera en la que se puede alojar al resto de
clientes de pie.
Las medidas de seguridad limitan a 20 el número de clientes que puede haber en el
establecimiento. En el ejemplo, procesaremos 50 clientes.
Restricciones:
●
Los clientes no entran a la tienda si ésta está al completo (20 clientes).
●
Si el sofá está completo, se espera de pie.
●
●
Cuando el barbero está libre, atiende al cliente que más tiempo lleva en el sofá, y el que
lleve más tiempo de pie, se sienta en el sofá.
Cuando finaliza un corte de pelo, el barbero cobra (sólo se puede cobrar uno a la vez porque
sólo hay una caja registradora); los barberos reparten el tiempo entre CORTAR_PELO,
COBRAR, DORMIR en su silla a la espera de clientes.
Problema de la Barbería - Semáforos
Solución NO equitativa:
Se soluciona el problema mediante los siguientes semáforos:
Problema de la Barbería - Semáforos
Solución NO equitativa:
// Inicialización:
semaforo max_capacidad;
semaforo sofa;
semaforo silla_barbero;
semaforo coord;
semaforo cliente_listo;
semaforo terminado;
semaforo dejar_silla;
semaforo pago;
semaforo recibo;
max_capacidad.contador = 20;
sofa.contador = 4;
silla_barbero.contador = 3;
coord.contador = 3;
cliente_listo.contador = 0;
terminado.contador = 0;
dejar_silla.contador = 0;
pago.contador = 0;
recibo.contador = 0;
// Programa principal:
void main() {
int i;
for (i = 1, i <= MAX_CLIENTES, i++)
insertar_cliente();
for (i = 1, i <= NUM_BARBEROS, i++)
insertar_barbero();
insertar_cajero();
}
Problema de la Barbería - Semáforos
Solución NO equitativa:
void cliente() {
wait(max_capacidad);
entrar_en_tienda();
wait(sofa);
sentarse_en_sofa();
wait(silla_barbero);
levantarse_del_sofa();
signal(sofa);
sentarse_en_silla_barbero();
signal(cliente_listo);
wait(terminado);
levantarse_de_silla();
signal(dejar_silla);
pagar();
signal(pago);
wait(recibo);
salir_tienda();
signal(max_capacidad);
}
void barbero() {
while(1) {
wait(cliente_listo);
wait(coord);
cortar_pelo();
signal(coord);
signal(terminado);
wait(dejar_silla);
signal(silla_barbero);
}
}
void cajero() {
while(1) {
wait(pago);
wait(coord);
aceptar_pago();
signal(coord);
signal(recibo);
}
}
Problema de la Barbería - Semáforos
Solución NO equitativa:
Esta solución no es equitativa porque puede ocurrir la siguiente situación:
●
●
●
Tres clientes están esperando a que se les corte el pelo => los tres estarán bloqueados en
la cola del semáforo terminado en orden de llegada.
Cuando a un cliente se le termina de cortar el pelo => el barbero hace signal(terminado).
Si suponemos que el último que llegó es el primero al que se termina de cortar el pelo
(barbero rápido o alopecia galopante), al ejecutar el barbero signal(terminado), se sacará
de la cola al primero que entró, ¡¡ aunque no se le haya terminado de cortar el pelo !!.
Mientras que el que terminó deberá esperar a que los otros dos clientes sean sacados de la
cola.
Problema de la Barbería - Semáforos
Solución Equitativa:
●
Se asigna un número único a cada cliente en su llegada:
●
Variable compartida contador, cuyo acceso está protegido por el semáforo binario exmut1.
●
●
●
●
terminado es un vector de semáforos, uno para cada cliente.
Cliente ejecuta wait(terminado[numCliente]) cuando se sienta para ser atendido -> espera en
su propio semáforo.
Barbero ejecuta signal(terminado[numCliente]) para liberar al cliente apropiado cuando
termina de atenderle.
Para que los barberos conozcan el número del cliente que van a atender, cada cliente inserta
su número en la cola cola1 justo antes de avisar al barbero a través del semáforo
cliente_listo. Cuando el barbero puede cortar el pelo, saca el número más bajo de la cola (el
primero que entró) y lo coloca en su variable local cliente_b.
Problema de la Barbería - Semáforos
Solución Equitativa:
// Inicialización:
semaforo max_capacidad;
max_capacidad.contador = 20;
semaforo sofa;
sofa.contador = 4;
semaforo silla_barbero;
silla_barbero.contador = 3;
semaforo coord;
coord.contador = 3;
exmut1.contador = 1;
semaforo exmut1;
exmut2.contador = 1;
semaforo exmut2;
cliente_listo.contador = 0;
semaforo cliente_listo;
dejar_silla.contador = 0;
semaforo dejar_silla;
pago.contador = 0;
semaforo pago;
recibo.contador = 0;
semaforo recibo;
semaforo terminado[MAX_CLIENTES];
for (int k = 0; k < MAX_CLIENTES; k++) terminado[k].contador = 0;
int contador = 0;
// Programa principal:
void main() {
for (int i = 1, i <= MAX_CLIENTES, i++) insertar_cliente();
for (int j = 1, j <= NUM_BARBEROS, j++) insertar_barbero();
insertar_cajero();
}
Problema de la Barbería - Semáforos
Solución Equitativa:
void barbero() {
int cliente_b;
while(1) {
wait(cliente_listo);
wait(exmut2);
sacar_cola(cliente_b);
signal(exmut2);
wait(coord);
cortar_pelo();
signal(coord);
signal(terminado[cliente_b]);
wait(dejar_silla);
signal(silla_barbero);
}
}
void cajero() {
while(1) {
wait(pago);
wait(coord);
aceptar_pago();
signal(coord);
signal(recibo);
}
}
void cliente() {
int numCliente;
wait(max_capacidad);
entrar_en_tienda();
wait(exmut1);
contador++; numCliente = contador;
signal(exmut1);
wait(sofa);
sentarse_en_sofa();
wait(silla_barbero);
levantarse_del_sofa();
signal(sofa);
wait(exmut2);
poner_cola1(numCliente);
signal(exmut2);
signal(cliente_listo);
sentarse_en_silla_barbero();
wait(terminado[numCliente]);
levantarse_de_silla();
signal(dejar_silla);
pagar();
signal(pago);
wait(recibo);
salir_tienda();
signal(max_capacidad);
}
4.1.4. REGIONES CRÍTICAS.
Regiones Críticas
“Problemas” de los semáforos:
●
●
●
Alta probabilidad de equivocación por parte del programador.
Los compiladores no ayudan al programador en su uso eficiente.
Un uso incorrecto de los semáforos puede dar lugar a errores de temporización
difíciles de detectar (falta semántica que ayude)
El concepto de región crítica (RC) fue
introducido por Hansen en 1972:
●
Una RC es un “constructor” que
resuelve el problema de exclusión
mutua estableciendo un mecanismo
de
acceso
a
los
recursos
compartidos.
Regiones Críticas
Características de las RC:
●
●
●
●
●
El compilador implementa automáticamente los mecanismos necesarios para
sincronizar el acceso a cada RC.
Cada recurso compartido debe ser definido como shared.
Existirá una RC para cada recurso compartido.
No está permitido el acceso al recurso compartido fuera de la RC.
Cada RC tiene asociada una cola para aquellos procesos que esperan a que la
RC sea liberada.
Declaración de recurso compartido (sintaxis tipo “Pascal Concurrente”)
var v: shared T;
(* Variable compartida v de tipo T *)
Constructor:
region v do
begin
<sección crítica>
end;
Regiones Críticas
Problema de las RC:
●
La sincronización entre procesos que aguardan por una condición puede necesitar
espera activa.
Ejemplo:
...
repeat
region v do
begin
ok := (v > 0);
if ok then
v := v - 1;
end;
until ok;
...
●
(* Hay espera activa en repeat *)
(* Solo un proc. ejecuta la RC *)
Solución: incluir una condición de “guarda” para cada RC. Son las regiones
críticas condicionales (RCC).
Regiones Críticas Condicionales
Características de las RCC:
●
●
●
La idea es similar a las RC, con la diferencia de que se añade una condición de
guarda en la región crítica.
La evaluación de la condición se considera parte de la región crítica.
Un proceso ejecuta el código limitado por la RCC sólo si la condición es cierta.
Sintaxis:
region v when cond do
begin
<sección crítica>
end;
Hansen propuso la siguiente
implementación con dos colas
Productor / Consumidor - RCCs
(* Productor / Consumidor BUFFER LIMITADO *)
PROGRAM ProdCons;
CONST MAX=50;
OJO: el registro protegido
TYPE
se compone de buffer +
TBuffer = RECORD
índices
sigent, sigsal, cont: INTEGER;
elems: ARRAY [1..MAX] OF INTEGER;
END;
VAR buffer : SHARED TBuffer;
PROCESS Productor;
VAR pdato: INTEGER;
BEGIN
...
pdato := producir();
REGION buffer WHEN buffer.cont<MAX DO
BEGIN
buffer.elems[buffer.sigent] := pdato;
buffer.sigent := (buffer.sigent MOD MAX) + 1;
buffer.cont := buffer.cont + 1;
END;
...
END;
Productor / Consumidor - RCCs
PROCESS Consumidor;
VAR cdato: INTEGER;
BEGIN
...
REGION buffer WHEN buffer.cont<>0 DO
BEGIN
cdato := buffer.elems[buffer.sigsal];
buffer.sigsal := (buffer.sigsal MOD MAX) + 1;
buffer.cont := buffer.cont - 1;
END;
...
END;
BEGIN (* Principal *)
(* Inicialización del buffer *)
REGION buffer WHEN true DO
BEGIN
buffer.sigent:=1; buffer.sigsal:=1; buffer.cont := 0;
END;
COBEGIN
Productores; Consumidores; (* Generaría varios de cada uno *)
COEND;
END.
4.1.5. MONITORES.
Monitores
Estructuras con funcionalidad equivalente a la de los semáforos:
●
Resuelven el acceso en exclusión mutua a recursos compartidos.
●
Permiten sincronización entre procesos evitando espera activa.
●
Más sencillos de programar que los semáforos.
●
Las operaciones que contienen proporcionan semántica.
●
Se han usado en diversos lenguajes de programación:
PASCAL FC
●
Modula-2
●
JAVA (synchronized)
http://www.artima.com/insidejvm/ed2/threadsynchP.html
●
Dos tipos de monitores:
●
Monitores con señales (Hoare).
●
Monitores con notificación y difusión (Lampson y Redell).
Monitores con Señales
Propuestos por primera vez por Hoare en 1974
•
•
Biografía de Tony Hoare: http://es.wikipedia.org/wiki/C._A._R._Hoare
Inventor del algoritmo Quicksort, profesor emérito en Oxford, actualmente
vinculado a Microsoft
http://research.microsoft.com/users/thoare/
Un monitor con señales es un módulo SW que consta de uno o más procedimientos, una
secuencia de inicialización y unos datos locales.
Características básicas:
●
●
●
Las variables locales sólo pueden ser accedidas por los procedimientos del monitor.
Los procesos “entran” en el monitor invocando a uno de los procedimientos contenidos en
él.
Sólo un proceso puede ejecutar código del monitor en cada instante, otros procesos que
hayan invocado al monitor quedarán suspendidos.
Monitores con Señales
Exclusión Mutua:
●
El acceso a una estructura de datos (o recurso) compartida puede protegerse declarándola
dentro de un monitor y programando accedentes como procedimientos del monitor.
Sincronización:
●
Un monitor proporciona sincronización a través de variables de condición que se colocan
dentro del monitor. Las operaciones que permiten trabajar con esas variables son:
cwait(c): suspende la ejecución del proceso que llama bajo la variable de condición c y lo
coloca en una cola de procesos vinculada esa condición. El monitor pasa a estar disponible.
csignal(c): reanuda la ejecución de algún proceso suspendido después de un cwait bajo la
misma condición. Si hay varios procesos, elige uno de ellos; si no hay ninguno, no hace nada.
Monitores con Señales
Cola de entrada
al monitor
Estructura de monitor:
Zona de Espera
MONITOR
Cond c1
Datos Locales
cwait(c1)
...
Cond cn
Variables Condición
Procedimiento 1
...
cwait(cn)
Salida
Procedimiento k
Urgentes
csignal
Código de Inicialización
Los procesos van a “Urgentes” si no invocan csignal como última instrucción del procedimiento.
Prod. / Cons. - Monitores Señales
Productor / Consumidor Buffer Limitado.
Monitor buffer_acotado;
// Inicio del bloque monitor.
int buffer[1..N];
// Vars. del monitor (buffer limitado)
int sigent, sigsal;
int contador;
int tomar() {
condition no_lleno, no_vacio;
int y;
if (contador == 0)
void aniadir(int x) {
cwait(no_vacio);
if (contador == N)
y = buffer[sigsal];
cwait(no_lleno);
sigsal = (sigsal + 1) % N;
buffer[sigent] = x;
contador--;
sigent = (sigent + 1) % N;
csignal(no_lleno);
contador++;
return y;
csignal(no_vacio);
}
}
{
sigsal = 0; /* Código de inicialización del monitor. */
sigent = 0;
contador = 0;
} // Fin del monitor
Monitores con Notificación y Difusión
Propuestos por Lampson y Redell en 1980 para el lenguaje Mesa.
Inconvenientes de la solución de Hoare:
●
●
●
Si hay al menos un proceso en una cola de condición, el proceso que ejecuta csignal sobre
esa cola debe salir inmediatamente del monitor o suspenderse en él (cola de urgentes):
Si el proceso que ejecuta csignal no terminó de ejecutar instrucciones del monitor, se
necesitan dos cambios de contexto.
La planificación debe ser estricta porque la condición podría cambiar.
Solución de Lampson y Redell:
●
●
Se sustituye el csignal por cnotify, con la siguiente interpretación:
cnotify(c): cuando un proceso ejecuta cnotify(c), se notifica al primer proceso de la cola c
que se reanudará en breve, pero como no le asegura la reanudación inmediata, éste habrá de
comprobar de nuevo la condición antes de poder seguir ejecutándose.
Monitores con Notificación y Difusión
Productor / Consumidor con notificación y difusión:
void aniadir(int x) {
}
while (contador == N)
cwait(no_lleno);
buffer[sigent] = x;
sigent = (sigent + 1) % N;
contador++;
cnotify(no_vacio);
int tomar() {
int y;
while (contador == 0)
cwait(no_vacio);
y = buffer[sigsal];
sigsal = (sigsal + 1) % N;
contador--;
cnotify(no_lleno);
return y;
}
●
●
Se sustituyen los if por while para que los procesos vuelvan a comprobar las condiciones
(cnotify no garantiza que al retomar la ejecución la condición se cumpla).
En la mayoría de los casos, cnotify evita los dos cambios de contexto.
Monitores con Notificación y Difusión
Mejoras en monitores con notificación y difusión:
●
Asociar un temporizador a las colas de condición que limite el tiempo de bloqueo.
●
Evita la inanición si un proceso falla antes de enviar la señal.
●
Primitiva extra para monitores con notificación y difusión:
cbroadcasting(c): ocasiona que todos los procesos en espera de que se cumpla una condición,
pasen a estar en la cola de listos.
Ventaja fundamental de los monitores con notificación y difusión:
●
Es más complicado que los errores de programación afecten al sistema porque, aún
mandando una señal equívoca, los procesos deben comprobar la condición al volver a
ejecutar.
4.1.6 PASO DE MENSAJES.
Paso de Mensajes
El mecanismo de paso de mensajes permite:
●
Sincronizar procesos (exclusión mutua).
●
Intercambiar información entre los procesos que lo necesiten.
Método fácilmente implementable en
monoprocesador de memoria compartida.
sistemas
distribuidos,
multiprocesador
y
Hay diversas implementaciones del mecanismo de paso de mensajes, aunque habitualmente se
ofrece su soporte a través de dos primitivas:
●
●
send(destino, mensaje)
●
receive(origen, &mensaje)
Éste es el conjunto mínimo de operaciones para que dos procesos puedan dedicarse al
paso de mensajes. destino y origen son identificadores de los procesos destinatario y
fuente del mensaje.
Paso de Mensajes
Características de la implementación del paso de mensajes:
Sincronización: un proceso receptor no puede obtener un mensaje hasta que no sea enviado
por otro proceso.
●
●
●
●
●
●
●
●
●
Se debe especificar qué ocurre después de que un proceso ejecute send ó receive.
Posibilidades: detenerse (bloquearse) o no.
Envío bloqueante, recepción bloqueante (rendezvous).
Fuerte sincronización entre procesos.
Envío no bloqueante, recepción bloqueante.
Útil en programación, evitando emisores “desbocados”.
Envío no bloqueante, recepción no bloqueante.
Nadie debe esperar.
“Peligroso” en programación.
Envío bloqueante, recepción no bloqueante.
Paso de Mensajes
●
●
●
●
●
●
●
●
●
Direccionamiento: especificación de emisor y receptor de los mensajes. Tipos de
direccionamiento:
Direccionamiento directo:
send: incluye la identificación del proceso destino del mensaje.
receive: hay dos maneras de gestionarlo.
Designación explícita del emisor.
Éste no siempre es conocido de antemano
Muy recomendable para cooperación entre procesos.
Designación implícita: el parámetro origen tomará un valor de retorno cuando ya se haya completado
la operación.
Direccionamiento indirecto (buzones). Ventajas:
●
Se desacopla la relación emisor – receptor. Relaciones diversas:
●
Uno a uno: impide errores y da privacidad a la comunicación.
●
Uno a muchos: difusión
●
Muchos a uno: cliente/servidor, el buzón pasa a ser un puerto.
Paso de Mensajes
Direccionamiento indirecto (buzones), continúa:
La asociación de buzones a procesos puede ser:
●
●
●
Estática: los puertos suelen estar asignados estáticamente. Un puerto se crea y se asigna a
un proceso definitivamente.
Dinámica: cuando hay varios emisores, la asociación de un emisor a un buzón puede
realizarse dinámicamente.
Necesarias primitivas de conexión y desconexión del buzón.
Propietario de un buzón:
●
Un puerto normalmente pertenece y es creado por el receptor.
●
Un buzón es propiedad del proceso que lo crea (sea emisor o receptor).
●
Cuando un proceso se destruye, también se destruyen los buzones que poseyera.
Paso de Mensajes
Formato de mensajes: el formato de los mensajes depende de los objetivos del sistema de
mensajería.
Mensajes cortos y de tamaño fijo:
Mejor procesamiento y ahorro en coste de almacenamiento.
El mensaje puede ser la referencia a un archivo.
Formato típico de un mensaje:
Cabecera, con información relativa al mensaje. Longitud fija.
Cuerpo, contenido real del mensaje. Longitud variable.
Paso de Mensajes
Disciplina de cola del buzón:
Habitualmente FIFO:
Insuficiente para mensajes urgentes.
Alternativas a FIFO:
Asociación de prioridades en el emisor.
Permitir al receptor examinar los mensajes de la cola y elegir uno en función de su criterio.
Exclusión mutua: recepción bloqueante, token.
Antes de acceder a la sección crítica, todo proceso debe recibir un mensaje que le indique la
entrada.
Tras recibirlo, ejecuta la sección crítica
Al terminar la sección crítica envía un mensaje para los próximos procesos.
Paso de Mensajes
Exclusión mutua: implementación.
const int N = 20;
void P() {
mensaje msg;
while(1) {
receive(exmut, &msg);
<Sección crítica>
send(exmut, msg);
// Resto del código de P.
}
}
// Numero de procesos.
// Recepción BLOQUEANTE
// Envío no bloqueante
void main() {
crear_buzon(exmut);
/* Envío de mensaje vacío para que el primer proceso pueda
entrar en su sección crítica. */
send(exmut, NULL);
// Genera N procesos P().
genera_P(N);
}
Prod. / Cons. - Paso de Mensajes
Productor / Consumidor Buffer Limitado.
const int capacidad = N;
void productor() {
mensaje msg;
while(1) {
receive(p_producir,&msg);
msg = producir();
send(p_consumir,msg);
}
}
void main() {
crear_buzon(p_producir); crear_buzon(p_consumir);
for (int i = 1; i <= N; i++)
send(p_producir,NULL);
pid_t pid = fork();
switch(pid) {
case –1: printf(“Error, no funcionó fork”); break;
case 0: consumidor(); break; // Código del hijo.
default: productor(); break;
// Código del padre.
}
void consumidor() {
mensaje msg;
while(1) {
receive(p_consumir,&msg);
consumir(msg);
send(p_producir,msg)
}
}
4.1.7. LLAMADA A PROCEDIMIENTOS
REMOTOS (RPC).
RPC
Los procedimientos conforman fronteras naturales para la división de los programas en
procesos:
●
Interfaces propios, puntos de entrada y puntos de salida.
●
RPC hace transparentes al programador los sistemas distribuidos.
Aspectos a tener en cuenta:
●
Transferencia de control
●
Vinculación ó enlace
●
Flujo de datos
Transferencia de control:
●
Suspensión del proceso invocante
●
Transferencia de datos al sistema invocado.
●
Ejecución del procedimiento remoto
●
Devolución de los resultados
●
Reanudación del proceso invocante
RPC
Transferencia de control: (sigue)
●
Incorpora el concepto de sustituto (stub) de usuario para representar al procedimiento
al que se llama de modo remoto.
LOCAL
Usuario
Sustituto de
servidor
Llamada
local
Empaquetar
argumentos
REMOTO
Ejecutable
RPC
Tx
Ejecutable
RPC
Rx
Sustituto de
usuario
Servidor
Desempaquetar
argumentos
Llamada
Esperar
Retorno
local
Desempaquetar
argumentos
Rx
Ejecución
Tx
Empaquetar
argumentos
Retorno
RPC
Vinculación:
●
●
●
Proceso consistente en dos pasos:
Localización de módulos de componentes
Resolución de referencias a direcciones para producir la imagen
Flujo de Datos:
●
●
Paso de parámetros:
El problema es la homogeneidad de los datos. Estándares !!
RPC es un protocolo de comunicación implementado en diversos SSOO y lenguajes de
programación
Related documents