You are on page 1of 59

dit UPM

Concurrencia
Juan Antonio de la Puente DIT/UPM

Objetivos
Repasaremos los principios de la programación concurrente Analizaremos la distintas alternativas de ejecución de procesos concurrentes Veremos cómo crear procesos concurrentes en Ada y C/POSIX

©1997-2000 Juan Antonio de la Puente

1

Índice
Introducción Ejecución concurrente Representación de procesos Tareas en Ada Threads en C / POSIX Ejemplo

©1997-2000 Juan Antonio de la Puente

2

Concurrencia
Los sistemas de tiempo real son concurrentes por naturaleza Las actividades del mundo exterior evolucionan simultáneamente Veremos cómo expresar de forma abstracta la ejecución de actividades potencialmente paralelas Los detalles de implementación son independientes de la programación concurrente

©1997-2000 Juan Antonio de la Puente

3

Ejemplo: paralelismo en E/S

procesador manejador iniciar E/S dispositivo interrupción

©1997-2000 Juan Antonio de la Puente

4

Sistemas concurrentes Un sistema concurrente se compone de un conjunto de procesos secuenciales autónomos que se ejecutan de forma (aparentemente) paralela Cada proceso tiene un flujo de control independiente – A veces se habla de procesos con varios flujos de control (threads) Las instrucciones de los procesos se ejecutan intercalándose unas con otras (paralelismo lógico) ©1997-2000 Juan Antonio de la Puente 5 .

Índice Introducción Ejecución concurrente Representación de procesos Tareas en Ada Threads en C / POSIX Ejemplo ©1997-2000 Juan Antonio de la Puente 6 .

Ejecución concurrente La forma de ejecutar las tareas concurrentes puede variar. según se ejecuten: – En un sistema monoprocesador: (multiprogramación) – En un sistema multiprocesador(fuertemente acoplado) (multiproceso) – En un sistema distribuido(débilmente acoplado) (procesamiento distribuido) En todos los casos hay que multiplexar el uso del procesador o procesadores entre los procesos ©1997-2000 Juan Antonio de la Puente 7 .

Estados de un proceso terminado inexistente creado iniciándose ejecutable ©1997-2000 Juan Antonio de la Puente 8 .

Núcleo de tiempo real Los procesos concurrentes se ejecutan con ayuda de un núcleo de ejecución (run-time kernel) – planificador (scheduler) en sistemas operativos El núcleo se encarga de la creación. terminación y el multiplexado de los procesos El núcleo puede tomar varias formas: – – – – Núcleo desarrollado como parte de la aplicación Núcleo incluido en el entorno de ejecución del lenguaje Núcleo de un sistema operativo de tiempo real Núcleo microprogramado El método de planificación que se usa afecta al comportamiento temporal del sistema ©1997-2000 Juan Antonio de la Puente 9 .

Procesos pesados y ligeros Los sistemas operativos suelen soportar procesos “pesados” – Cada proceso se ejecuta sobre una máquina virtual distinta Algunos sistemas operativos tienen procesos “ligeros” (threads) – Todos los threads de un mismo proceso comparten la misma máquina virtual – Tienen acceso al mismo espacio de memoria – El programador o el lenguaje deben proporcionar mecanismos para evitar interferencias entre unos y otros La concurrencia puede estar soportada por el lenguaje o solo por el sistema operativo ©1997-2000 Juan Antonio de la Puente 10 .

Concurrencia en lenguajes de programación Ventajas Programas más legibles y fáciles de mantener Programas más portátiles Se pueden detectar errores al compilar No hace falta sistema operativo Inconvenientes Distintos modelos de concurrencia según lenguajes Puede ser difícil de realizar eficientemente Se puede mejorar la portabilidad con SO normalizados ©1997-2000 Juan Antonio de la Puente 11 .

– cooperar para un fin común. – competir por el uso de recursos Los procesos que cooperan o compiten necesitan comunicarse y sincronizar sus actividades ©1997-2000 Juan Antonio de la Puente 12 .Lenguajes concurrentes Tienen elementos de lenguaje para – Crear procesos concurrentes – Sincronizar su ejecución – Comunicarse entre sí Los procesos pueden – ser independientes.

Características de los procesos Estructura – estática – dinámica Iniciación – paso de parámetros – comunicación explícita Nivel léxico – plano – anidado Terminación – – – – – – al completar la ejecución “suicidio” “aborto” excepción sin manejar cuando no hace falta nunca Granularidad – gruesa – fina ©1997-2000 Juan Antonio de la Puente 13 .

Jerarquía de procesos Proceso que crea otro – relación padre / hijo Si el padre espera durante la creación e iniciación del hijo – relación tutor / pupilo – el tutor puede ser » el padre » otro proceso » un bloque interno de uno de los anteriores – el tutor no puede terminar hasta que lo hayan hecho todos sus pupilos ©1997-2000 Juan Antonio de la Puente 14 .

Estados de un proceso terminado esperando terminación pupilo inexistente creado iniciándose ejecutable esperando inicio hijo ©1997-2000 Juan Antonio de la Puente 15 .

con control de acceso según su estado interno – necesitan un agente de control » Recursos protegidos: agente pasivo » Servidores: agente activo ©1997-2000 Juan Antonio de la Puente 16 . sin control de acceso (se ejecutan sin restricciones) Recursos – reactivos.Procesos y objetos Objetos activos – ejecutan acciones espontáneamente – tienen uno o más flujos de control (threads) propios Objetos reactivos – solo ejecutan acciones cuando se lo piden otros objetos Objetos pasivos – reactivos.

Diagramas de procesos proceso padre tutor hijo/ pupilo ©1997-2000 Juan Antonio de la Puente 17 .

Índice Introducción Ejecución concurrente Representación de procesos Tareas en Ada Threads en C / POSIX Ejemplo ©1997-2000 Juan Antonio de la Puente 18 .

Representación de procesos Hay varias formas de representar la ejecución concurrente en un lenguaje de programación – – – – – Corrutinas bifurcación y unión (fork/join) cobegin / coend declaración explícita de procesos declaración implícita de procesos ©1997-2000 Juan Antonio de la Puente 19 .

Corrutinas A 1 2 6 3 4 B C 5 resume B 7 resume A resume C 8 9 12 13 resume B 10 11 resume A 14 resume B resume C 15 Ejemplo: Modula-2 ©1997-2000 Juan Antonio de la Puente 20 .

fork / join Con fork se crea un nuevo proceso Con join se espera a que el proceso termine Ejemplo: C / POSIX.. c = join ().1 pid = fork().. /* se crea un proceso idéntico al original*/ .. /* el primero que llega espera al otro */ Flexible.. pero poco estructurado y propenso a errores En POSIX 1 se usa para crear procesos pesados ©1997-2000 Juan Antonio de la Puente 21 . .

C. occam2 ©1997-2000 Juan Antonio de la Puente 22 . coend.A.espera a que terminen A. y C Ejemplo: Edison. B.cobegin / coend Construcción estructurada cobegin -. B. -. B y C se ejecutan concurrentemente A.

Declaración explícita de procesos Los procesos son unidades de programa (como los procedimientos) Esto permite una mejor estructura A veces hay también creación implícita de procesos Ejemplo: Ada. C/POSIX ©1997-2000 Juan Antonio de la Puente 23 .

Índice Introducción Ejecución concurrente Representación de procesos Tareas en Ada Threads en C / POSIX Ejemplo ©1997-2000 Juan Antonio de la Puente 24 .

Tareas en Ada En Ada. las actividades concurrentes reciben el nombre de tareas Las tareas tienen dos partes: especificación y cuerpo – En la especificación se define la interfaz visible de la tarea » elementos de comunicación y otras cosas – En el cuerpo se describe la actividad de la tarea Las tareas se crean implícitamente cuando se entra se elabora su declaración Las tareas se empiezan a ejecutar antes que el cuerpo correspondiente a la parte declarativa donde se declaran ©1997-2000 Juan Antonio de la Puente 25 .

A y B empiezan a ejecutarse concurrentemente aquí -.se ejecuta concurrentemente con A y B end Example. begin -. -.secuencia de instrucciones. end B.secuencia de instrucciones. end A.especificación task B.no termina hasta que terminen A y B ©1997-2000 Juan Antonio de la Puente 26 .cuerpo -.declaraciones locales begin -. task body B is -.secuencia de instrucciones de Example -.declaraciones locales begin -. -. task body A is -.Ejemplo procedure Example is task A.

-. package body P is task A..Si P es un paquete de biblioteca. dentro de la secuencia -..se ejecutan al elaborarse el paquete. la creación e iniciación de A -. begin -. task body A is ..inicial del programa. end P.A empieza a ejecutarse aquí -.El programa no termina hasta que haya terminado A ©1997-2000 Juan Antonio de la Puente 27 .secuencia inicial de P end P.Tareas y paquetes package P is . -. end A..

Tipos tarea A veces es útil tener un grupo de tareas similares La declaración de un tipo tarea permite disponer de una plantilla para crear tareas similares Las declaraciones de tareas individuales son semejantes a las de otros objetos Las tareas que se declaran directamente (como antes) son de un tipo anónimo ©1997-2000 Juan Antonio de la Puente 28 .

. end B_Type. task body B_Type is . -. B : B_Type. A : A_Type. end A_Type.donde sea visible la declaración task body A_Type is . ©1997-2000 Juan Antonio de la Puente 29 .se pueden declarar objetos en cualquier punto -.. task type B_Type...Ejemplo task type A_Type.

Estructuras Se pueden declarar formaciones y registros con tareas task type T.. type Mixture is record Index : Integer. end record. B : T. A. type Long is array (1 . 100) of t. ©1997-2000 Juan Antonio de la Puente 30 . task body T is ... Action : T. end T.

-. Setting). C3 : Control (Zplane). task body Control is Position : Integer. begin null. Yplane. end Control. -. loop New_Setting (Dim.Discriminantes procedure Main is type Dimension is (Xplane. ©1997-2000 Juan Antonio de la Puente 31 . Position). Move_Arm (Dim.solo puede ser de un tipo discreto o de acceso C1 : Control (Xplane). Position := Position + Setting. end loop. -. Zplane).posición absoluta Setting : Integer. task type Control (Dim : Dimension).movimiento relativo begin Position := 0. C2 : Control (Yplane). end Main.Dim es un discriminante. -.

la antigua Q. ©1997-2000 Juan Antonio de la Puente 32 .all task body T is .. begin . -... -..Tareas dinámicas procedure Example is task type T. -.y otra más -.se crea otra tarea Q := new T. P := new T..la nueva tarea es Q. P : A.que se ejecuta inmediatamente. Q : A := new T.. end Example. type A is access T. -.aquí se crea una nueva tarea -.all sigue ejecutándose (pero es anónima) .

begin .bloque interior X : T..all es anónima aquí end. -..all .. -.Master.. -. pero no Y. -.all ©1997-2000 Juan Antonio de la Puente 33 .espera a que termine X.el amo de X es el bloque interior Y : A := new T. -.all es el bloque exterior begin ..Y.el amo de Y. declare -. end..ahora espera a que termine Y. amo o tutor El tutor (en Ada se llama master o amo) de una tarea dinámica es el bloque donde se declara el tipo acceso declare task type T. type A is access T.

-.ilegal P := Q. -.all. P.all := Q. P : A := new T. type A is access T. Q : A := new T.legal A veces se hace complicado – un mismo nombre puede designar tareas diferentes Es útil tener un identificador único para cada tarea ©1997-2000 Juan Antonio de la Puente 34 . ..Identificación de tareas Los tipos acceso permiten dar un nombre a las tareas Los tipos tarea son privados y limitados task type T..

Task_Identification. Null_Task_Id : constant Task_Id. private . (T : in out Task_ID).. function function function "=" (Left. Image (T : Task_ID) return String. end Ada. Is_Callable (T : Task_ID) return Boolean.Ada.definido en el anexo C . T'Identity proporciona la identidad de cualquier tarea ©1997-2000 Juan Antonio de la Puente 35 .Task_Identification package Ada.. Current_Task return Task_ID.Task_Identification is -.programación de sistemas type Task_Id is private. Además. Right : Task_ID) return Boolean. procedure Abort_Task function function Is_Terminated(T : Task_ID) return Boolean.

Activación Consiste en la elaboración de las declaraciones locales de una tarea – Las tareas estáticas se activan justo antes de empezar la ejecución del padre – Las tareas dinámicas se activan al ejecutarse el operador new El padre espera a que termine la activación de las tareas que ha creado Si se produce una excepción durante la activación. se eleva Tasking_Error en el padre ©1997-2000 Juan Antonio de la Puente 36 .

Terminación Una tarea esta completada cuando termina la ejecución de su secuencia de instrucciones Una tarea completada termina cuando todos sus pupilos han terminado Una tarea puede terminar también cuando: – Se pone de acuerdo con otras tareas para terminar conjuntamente (lo veremos más adelante) – Es abortada por otra tarea o por sí misma El atributo booleano T'Terminated es verdadero cuando T ha terminado ©1997-2000 Juan Antonio de la Puente 37 .

Abort_Task ©1997-2000 Juan Antonio de la Puente 38 .Aborto Una tarea puede abortar otra tarea cuyo nombre es visible mediante la instrucción abort T. Cuando se aborta una tarea.Task_Identification. también se abortan todos sus pupilos Problema: no se puede abortar una tarea anónima Se puede abortar una tarea identificada mediante el procedimiento Ada.

Índice Introducción Ejecución concurrente Representación de procesos Tareas en Ada Threads en C / POSIX Ejemplo ©1997-2000 Juan Antonio de la Puente 39 .

int pthread_join (pthread_t thread.... int pthread_create (pthread_t *thread. int pthread_attr_destroy (pthread_attr_t *attr)...h */ typedef . ©1997-2000 Juan Antonio de la Puente 40 .. pthread_t. /* tipo thread */ /* tipo atributos de thread */ int pthread_attr_init (pthread_attr_t *attr).. typedef .). pthread_t pthread_self (void).1c /* pthread. int pthread_exit (void *value_ptr). void *(*start_routine)(void *). void *arg).. pthread_attr_t.Procesos ligeros en C/POSIX. int pthread_attr_setstacksize (. int pthread_attr_getstacksize (... const pthread_attr_t *attr.). void **value_ptr). .

Ejemplo (1) #include "pthread. zplane} dimension. setting. /* the thread executing controller does not terminate */ } ©1997-2000 Juan Antonio de la Puente 41 . int new_setting (int D). position =0.h" typedef enum {xplane. zp. pthread_t xp. }. position). yplane. pthread_attr_t attributes. yp. while (1) { setting = new_setting (dim). int P). move_arm (dim. position = position + setting. void move_arm (int D. void *controller (dimension *dim) { int position.

Y = yplane. if (pthread_create (&xp. if (pthread_create (&zp. /* bloquear main */ } ©1997-2000 Juan Antonio de la Puente 42 . (void *)controller. &Z) != 0) exit (-1). void **)&result). if (pthread_attr_init(&attributes) != 0) exit (-1). (void *)controller. void *result. if (pthread_create (&yp. &attributes. pthread_join (xp. Z. &attributes. X = xplane. &attributes. &Y) != 0) exit (-1). &X) != 0) exit (-1). Z = zplane. (void *)controller. Y.Ejemplo (2) int main () { dimension X.

Índice Introducción Ejecución concurrente Representación de procesos Tareas en Ada Threads en C / POSIX Ejemplo ©1997-2000 Juan Antonio de la Puente 43 .

Aplicación: sistema de control termopar CAD T P CAD transductor calefactor SD S CDA válvula pantalla Se trata de mantener la temperatura y la presión dentro de ciertos límites ©1997-2000 Juan Antonio de la Puente 44 .

– Control de temperatura. pero sí un núcleo de ejecución ©1997-2000 Juan Antonio de la Puente 45 .Arquitectura de software Hay tres actividades concurrentes: – Control de presión. – Visualización. Se puede hacer de tres formas: – Con un solo programa secuencial (ejecutivo cíclico) No hace falta sistema operativo – Con tres procedimientos secuenciales ejecutados como procesos de un sistema operativo – Con un solo programa en un lenguaje concurrente No hace falta sistema operativo.

. ------- CAD CAD SD CDA pantalla pantalla with Data_Types. is is is is new Integer range 10 . out Valve_Setting). package Control_Procedures is procedure Control_Temperature (TR HS procedure Control_Pressure (PR VS end Control_Procedures. (On.10.. 750. use Data_Types. out Heater_Setting). Pressure). : : : : Temperature. new Integer range 0.Paquetes básicos package Data_Types is type Temperature type Pressure type Heater_Setting type Valve_Setting end Data_Types. Heater_Setting). package IO is procedure Read procedure Read procedure Write procedure Write procedure Write procedure Write end IO. Pressure. ©1997-2000 Juan Antonio de la Puente 46 . Temperature). (TR (PR (HS (VS (TR (PR : : : : : : out Temperature). new Integer range 0 .. Off). out Pressure). 500. Valve_Setting).

use IO. Control_Temperature (TR. with Control_Procedures. Write (VS). procedure Controller is TR : Temperature. VS : Valve_Setting. Read (PR). begin loop Read (TR). use Data_Types. VS). HS : Heater_Setting. HS). end Controller. use Control_Procedures. PR : Pressure. Control_Pressure (PR. end loop.Solución con ejecutivo cíclico with Data_Types. Write (HS). ©1997-2000 Juan Antonio de la Puente 47 . Write (TR). Write (PR). with IO.

deja de leerse el otro también ©1997-2000 Juan Antonio de la Puente 48 .Problemas La temperatura y la presión se muestrean con la misma frecuencia – se puede mejorar con un contador y estructuras if Mientras se espera leer una variable no se puede hacer nada con la otra Si un sensor falla.

end if. use Data_Types. end if. VS).. use IO.Solución mejorada with Data_Types. begin loop if Ready_Temperature then Read (TR). HS). if Ready_Pressure then Read (PR). with IO. Write (VS). Write (TR). with Control_Procedures. Control_Pressure (PR. end Controller. procedure Controller is . Write (PR). ©1997-2000 Juan Antonio de la Puente 49 . end loop. Control_Temperature (TR. use Control_Procedures.. Write (HS).

Crítica El programa pasa mucho tiempo en "espera ocupada" – es ineficiente Es difícil comprobar si funciona bien El principal problema es que dos actividades independientes están acopladas entre sí ©1997-2000 Juan Antonio de la Puente 50 .

procedure Create_Thread (Code : Thread_Code...Concurrencia basada en el sistema operativo package Operating_System_Interface is type Thread_Id is private. .. Id : out Thread_Id).. type Thread_Code is access procedure. ©1997-2000 Juan Antonio de la Puente 51 . end Operating_System_Interface.. private type Thread_Id is .

use Control_Procedures. end loop. with Control_Procedures. VS). end Temperature_Control. Control_Temperature (TR. use Data_Types. Write (TR). use Operating_System_Interface. Write (PR). with IO. end Pressure_Control.Solución con threads del sistema operativo (1) with Data_Types. with Operating_System_Interface. begin loop Read (PR). begin loop Read (TR). procedure Temperature_Control is TR : Temperature. ©1997-2000 Juan Antonio de la Puente 52 . Control_Pressure (PR. Write (HS). Write (VS). VS : Valve_Setting. procedure Pressure_Control is PR : Pressure. HS). procedure Controller is Temperature_Controller. Pressure_Controller : Thread_Id. use IO. HS : Heater_Setting. end loop.

otras actividades iniciales -. -.esperar a que terminen Temperature_Controller y Pressure_Controller end Controller. Pressure_Controller). ©1997-2000 Juan Antonio de la Puente 53 . Temperature_Controller).Controller Create_Thread (Temperature_Control'Access. Create_Thread (Pressure_Controler'Access.Solución con threads del sistema operativo (2) begin -.

POSIX) sería mucho más complicado No es fácil ver qué procedimientos son concurrentes (código de threads) Mejor con soporte directo del lenguaje ©1997-2000 Juan Antonio de la Puente 54 .Crítica De esta forma se desacoplan completamente las dos actividades Con un sistema operativo real (p. ej.

with IO. Write (VS). end Pressure_Controller. end loop. procedure Controller is task Temperature_Controller. Control_Pressure (PR. task body Temperature_Controller is TR : Temperature. Write (PR). task body Pressure_Controller is PR : Pressure. VS : Valve_Setting. VS). Write (HS). HS).Solución con un lenguaje concurrente (1) with Data_Types. end loop. begin loop Read (PR). use IO. Control_Temperature (TR. ©1997-2000 Juan Antonio de la Puente 55 . end Temperature_Controller. use Data_Types. begin loop Read (TR). Write (TR). with Control_Procedures. HS : Heater_Setting. task Pressure_Controller. use Control_Procedures.

Solución con un lenguaje concurrente (2) begin -.Controller null. Es más fácil de escribir y leer El código refleja directamente el paralelismo de la aplicación ©1997-2000 Juan Antonio de la Puente 56 . end Controller.

el resultado es ilegible Hace falta un mecanismo para la gestión de recursos – sincronización de tipo exclusión mutua – hace falta el apoyo del entorno de ejecución ©1997-2000 Juan Antonio de la Puente 57 .Problemas Ambas tareas envían datos a la pantalla – hay que gestionar el acceso a este recurso compartido – si la escritura no se hace de forma exclusiva por cada tarea.

Se pueden ejecutar estas actividades dentro de un programa secuencial mediante un ejecutivo cíclico. Se pueden definir tipos tarea y tareas dinámicas con tipos de acceso. con especificación y cuerpo.1c define una interfaz de sistema operativo para threads (procesos concurrentes con memoria compartida) ©1997-2000 Juan Antonio de la Puente 58 . pero con serios inconvenientes. Las tareas de Ada son unidades de programa. La norma POSIX. Las tareas de Ada también son objetos (limitados). Los procesos concurrentes o tareas permiten descomponer un sistema en actividades concurrentes de forma natural.Resumen Los sistemas de tiempo real suelen realizar varias actividades en paralelo.