

























































































Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Prepara tus exámenes
Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Prepara tus exámenes con los documentos que comparten otros estudiantes como tú en Docsity
Encuentra los documentos específicos para los exámenes de tu universidad
Estudia con lecciones y exámenes resueltos basados en los programas académicos de las mejores universidades
Responde a preguntas de exámenes reales y pon a prueba tu preparación
Consigue puntos base para descargar
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Comunidad
Pide ayuda a la comunidad y resuelve tus dudas de estudio
Ebooks gratuitos
Descarga nuestras guías gratuitas sobre técnicas de estudio, métodos para controlar la ansiedad y consejos para la tesis preparadas por los tutores de Docsity
Asignatura: fp fundamentos de prgramación, Profesor: silvia acid, Carrera: Ingeniería Informática, Universidad: UGR
Tipo: Ejercicios
1 / 97
Esta página no es visible en la vista previa
¡No te pierdas las partes importantes!


























































































Carlos Ureña / Jose M. Mantas / Pedro Villar 2017-
Grado en Ingeniería Informática / Grado en Ingeniería Informática y Matemáticas. Dpt. Lenguajes y Sistemas Informáticos ETSI Informática y de Telecomunicación Universidad de Granada
Sistemas Concurrentes y Distribuidos., curso 2017-18. Seminario 1. Programación multihebra y semáforos. Índice.
Sistemas Concurrentes y Distribuidos., curso 2017-18. Seminario 1. Programación multihebra y semáforos. Sección 1. Concepto e Implementaciones de Hebras.
En un instante pueden existir muchos procesos ejecutándose concurrentemente, cada proceso corresponde a un programa en ejecución y ocupa una zona de memoria con (al menos) estas partes:
I texto: zona (tamaño fijo) con las instrucciones del programa I datos: espacio (de tamaño fijo) para variables globales. I pila: espacio (de tamaño cambiante) para variables locales. I mem. dinámica ( heap ): espacio ocupado por variables dinámicas.
Cada proceso tiene asociados (entre otros) estos datos: I contador de programa (pc): dirección en memoria (en la zona de texto) de la siguiente instrucción a ejecutar. I puntero de pila (sp): dirección en memoria (en la zona de pila) de la última posición ocupada por la pila.
En el siguiente programa escrito en C/C++, el estado del proceso (durante la ejecución de k=1; ) es el que se ve a la derecha: int a,b,c ; // variables globales void subprograma1() { int i,j,k ; // vars. locales (1) k = 1 ; } void subprograma2() { float x ; // vars. locales (2) subprograma1() ; } int main() { char * p = new char ; // ”p”local p = |a|; // ”p.en^ el heap subprograma2() ; }
Proceso pc sp texto … k=1; … datos a,b,c pila p x i,j,k heap *p
La gestión de varios procesos no independientes (cooperantes) es muy útil pero consume una cantidad apreciable de recursos del SO:
I Tiempo de procesamiento para repartir la CPU entre ellos I Memoria con datos del SO relativos a cada proceso I Tiempo y memoria para comunicaciones entre esos procesos
para mayor eficiencia en esta situación se diseñó el concepto de hebra:
I Un proceso puede contener una o varias hebras. I Una hebra es un flujo de control en el texto (común) del proceso al que pertencen. I Cada hebra tiene su propia pila (vars. locales), vacía al inicio. I Las hebras de un proceso comparten la zona de datos (vars. globales), y el heap.
Al inicio de un programa, existe una única hebra (que ejecuta la función main en C/C++). Durante la ejecución del programa: I Una hebra A en ejecución puede crear otra hebra B en el mismo proceso de A I Para ello, A designa un subprograma f (una función C/C++) del texto del proceso (y opcionalmente sus parámetros), y después continúa su ejecución. La hebra B: I ejecuta la función f concurrentemente con el resto de hebras. I termina normalmente cuando finaliza de ejecutar dicha función (bien ejecutando return o bien cuando el flujo de control llega al final de f) I Una hebra puede esperar a que cualquier otra hebra en ejecución finalice (y opcionalmente puede obtener un valor resultado)
En main se crean dos hebras, después se llega al estado que vemos: int a,b,c ; void subprograma1() { int i,j,k ; // ... } void subprograma2() { float x ; // ... } int main() { char * p = new char ; // crear hebra (subprog.1) // crear hebra (subprog.2) // ... }
Proceso texto subprograma1(){ … } subprograma2(){ … } main() { … } datos a,b,c heap *p Hebra 0 pc sp pila p
Hebra 1 pc sp pila x
Hebra 2 pc sp pila i,j,k
El acrónimo C++11 designa la versión del lenguaje de programación C++ publicada por ISO (la International Standards Organization ) en Septiembre de 2011.
I Denominado oficialmente como estándard ISO/IEC 14882:2011: I Página del estándard en la web de ISO: https://www.iso.org/standard/50372.html I Borrador revisado en PDF: https://github.com/cplusplus/draft/blob/master/papers/n3337.pdf I Hay una revisión posterior de C++ del 2014, pero no modifica los aspectos básicos que veremos aquí. I Los fuentes C++ que usan este estándard son portables a Linux, macOS y Windows. I Los compiladores de código abierto de GNU (g++) y del proyecto LLVM (clang++), así como Visual C++ implementan este estándard.
Sistemas Concurrentes y Distribuidos., curso 2017-18. Seminario 1. Programación multihebra y semáforos. Sección 2. Hebras en C++ Subsección 2.1. Introducción a las hebras en C++11.
Sistemas Concurrentes y Distribuidos., curso 2017-18. Seminario 1. Programación multihebra y semáforos. Sección 2. Hebras en C++ Subsección 2.2. Creación y finalización de hebras.
El tipo de datos (o clase) std::thread permite definir objetos (variables) de tipo hebra. Un objeto (una variable) de este tipo puede contener información sobre una hebra en ejecución.
I En la declaración de la variable, se indica el nombre de la función que ejecutará la hebra I En tiempo de ejecución, cuando se crea la variable, se comienza la ejecución concurrente de la función por parte de la nueva hebra. I En la declaración se pueden especificar los parámetros de la nueva hebra. I La variable sirve para poder referenciar a la hebra posteriormente.
En el ejemplo anterior, las hebras se ponen en marcha cuando el flujo de control llega a la declaración de las variables tipo hebra: thread hebra1( funcion_hebra_1 ), // crear hebra1 ejecutando funcion_hebra_ hebra2( funcion_hebra_2 ); // crear hebra2 ejecutando funcion_hebra_ Sin embargo, también es posible declarar las variables y después poner en marcha las hebras. Para ello, en la declaración no incluimos la función a ejecutar: thread hebra1, hebra2 ; // declaraciones (no se ejecuta nada) .... hebra1 = thread( funcion_hebra_1 ); // hebra1 comienza funcion_hebra_ hebra2 = thread( funcion_hebra_2 ); // hebra2 comienza funcion_hebra_ Entre la declaración y el inicio (en los puntos suspensivos), las variables de tipo hebra no tienen asociada ninguna hebra en ejecución (esto permite variables tipo hebra globales).
Una hebra cualquiera A que está ejecutando f finaliza cuando:
I La hebra A llega al final de f. I La hebra A ejecuta un return en f. I Se lanza una excepción que no se captura en f ni en ninguna función llamada desde f. I Se destruye la variable tipo hebra asociada (es un situación de error, a evitar).
Todas las hebras en ejecución de un programa finalizan cuando: I Cualquiera de ellas llama a la función exit() (o abort, o terminate), en este caso se termina el proceso completo. I La hebra principal termina de ejecutar main (esta es una situación de error, que debemos de evitar, y que ocure en el ejemplo visto).