gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como...

25
UNIDAD 3 PROGRAMACION CONCURRENTE MULTIHILO 3.1 Concepto de Hilo: hilos no pueden ejecutarse ellos solos; requieren la supervisión de un proceso padre para correr. Dentro de cada proceso hay varios hilos ejecutándose. hilo puede estar salvando automáticamente los cambios del documento en el que estoy trabajando. Como Word, cada aplicación (proceso) puede correr varios hilos los cuales están realizando diferentes tareas. Esto significa que los hilos están siempre asociados con un proceso en particular. Los hilos a menudo son conocidos o llamados procesos ligeros. Un hilo, en efecto, es muy similar a un proceso pero con la diferencia de que un hilo siempre corre dentro del contexto de otro programa. Por el contrario, los procesos mantienen su propio espacio de direcciones y entorno de operaciones. Los hilos dependen de un programa padre en lo que se refiere a recursos de ejecución. La siguiente figura muestra le relación entre hilos y procesos. Un programa de flujo único o mono-hilvanado (single-thread) utiliza un único flujo de control (thread) para controlar su ejecución. Muchos programas no necesitan la potencia o utilidad de múltiples flujos de control. Sin necesidad de especificar explícitamente que se quiere un único flujo de control, muchos de los applets y aplicaciones son de flujo único. Por ejemplo, en nuestra aplicación estándar de saludo: public class hola { static public void main( String args [] ) { System.out.println( “ +++++ Hola Mundo ++++” ); } }

Transcript of gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como...

Page 1: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo

UNIDAD 3

PROGRAMACION CONCURRENTE MULTIHILO

3.1 Concepto de Hilo:

hilos no pueden ejecutarse ellos solos; requieren la supervisión de un proceso padre para correr. Dentro de cada proceso hay varios hilos ejecutándose. hilo puede estar salvando automáticamente los cambios del documento en el que estoy trabajando. Como Word, cada aplicación (proceso) puede correr varios hilos los cuales están realizando diferentes tareas. Esto significa que los hilos están siempre asociados con un proceso en particular. Los hilos a menudo son conocidos o llamados procesos ligeros. Un hilo, en efecto, es muy similar a un proceso pero con la diferencia de que un hilo siempre corre dentro del contexto de otro programa. Por el contrario, los procesos mantienen su propio espacio de direcciones y entorno de operaciones. Los hilos dependen de un programa padre en lo que se refiere a recursos de ejecución. La siguiente figura muestra le relación entre hilos y procesos. Un programa de flujo único o mono-hilvanado (single-thread) utiliza un único flujo de control (thread) para controlar su ejecución. Muchos programas no necesitan la potencia o utilidad de múltiples flujos de control. Sin necesidad de especificar explícitamente que se quiere un único flujo de control, muchos de los applets y aplicaciones son de flujo único.

Por ejemplo, en nuestra aplicación estándar de saludo:

public class hola { static public void main( String args [] ) { System.out.println( “ +++++ Hola Mundo ++++” ); } }

Page 2: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo

3.2 Comparación de un Programa de Flujo Único Contra una de Flujo Múltiple:

Programas de flujo único

Un programa de flujo único o mono-hilvanado (single-thread) utiliza un único flujo de control (thread) para controlar su ejecución. Muchos programas no necesitan la potencia o utilidad de múltiples flujos de control. Sin necesidad de especificar explícitamente que se quiere un único flujo de control, muchos de los applets y aplicaciones son de flujo único.

Por ejemplo, en la archiconocida aplicación estándar de saludo:

public class { static public void main( String args[] ) {

System.out.println( “Hola Mundo!” );

}

}

Aquí, cuando se llama a main(), la aplicación imprime el mensaje y termina. Esto ocurre dentro de un único hilo de ejecución (thread).

Debido a que la mayor parte de los entornos operativos no solían ofrecer un soporte razonable para múltiples hilos de control, los lenguajes de programación tradicionales, tales como C++, no incorporaron mecanismos para describir de manera elegante situaciones de este tipo. La sincronización entre las múltiples partes de un programa se llevaba a cabo mediante un bucle de suceso único. Estos entornos son de tipo síncrono, gestionados por sucesos. Entornos tales como el de Macintosh de Apple, Windows de Microsoft y X11/Motif fueron diseñados en torno al modelo de bucle de suceso.

Programas de flujo múltiple

En la aplicación de saludo, no se ve el hilo de ejecución que corre el programa. Sin embargo, Java posibilita la creación y control de hilos de ejecución explícitamente. La utilización de hilos (threads) en Java, permite una enorme

Page 3: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo

flexibilidad a los programadores a la hora de plantearse el desarrollo de aplicaciones. La simplicidad para crear, configurar y ejecutar hilos de ejecución, permite que se puedan implementar muy poderosas y portables aplicaciones/applets que no se puede con otros lenguajes de tercera generación. En un lenguaje orientado a Internet como es Java, esta herramienta es vital.

Si se ha utilizado un navegador con soporte Java, ya se habrá visto el uso de múltiples hilos en Java. Habrá observado que dos applets se pueden ejecutar al mismo tiempo, o que puede desplazar la página del navegador mientras el applet continúa ejecutándose. Esto no significa que el applet utilice múltiples hiloss, sino que el navegador es multihilo, multihilvanado o multithreaded.

Los navegadores utilizan diferentes hilos ejecutándose en paralelo para realizar varias tareas, “aparentemente” concurrentemente. Por ejemplo, en muchas páginas web, se puede desplazar la página e ir leyendo el texto antes de que todas las imágenes estén presentes en la pantalla. En este caso, el navegador está trayéndose las imágenes en un hilo de ejecución y soportando el desplazamiento de la página en otro hilo diferente.

Las aplicaciones (y applets) multihilo utilizan muchos contextos de ejecución para cumplir su trabajo. Hacen uso del hecho de que muchas tareas contienen subtareas distintas e independientes. Se puede utilizar un hilo de ejecución para cada subtarea.

Mientras que los programas de flujo único pueden realizar su tarea ejecutando las subtareas secuencialmente, un programa multihilo permite que cada thread comience y termine tan pronto como sea posible. Este comportamiento presenta una mejor respuesta a la entrada en tiempo real.

Vamos a modificar el programa de saludo creando tres hilos de ejecución individuales, que imprimen cada uno de ellos su propio mensaje de saludo, Multi Hola.java:

// Definimos unos sencillos hilos. Se detendrán un rato

// antes de imprimir sus nombres y retardos

class Test Th? extends Thread { private String nombre;

Page 4: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo

private int retardo;

// Constructor para almacenar nuestro nombre

// y el retardo

public Test Th( String s,int d ) {

nombre = s;

retardo = d;

}

// El metodo run() es similar al main(), pero para

// threads. Cuando run() termina el thread muere

public void run() {

// Retasamos la ejecución el tiempo especificado

try {

sleep( retardo );

} catch( Interrupted Exception e ) {

;

}

Page 5: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo

// Ahora imprimimos el nombre

System.out.println( “Hola Mundo! “+nombre+” “+retardo );

}

}

public class Multi Hola { public static void main( String args[] ) {

Test Th t1,t2,t3;

// Creamos los threads

t1 = new Test Th( “Thread 1″,(int)(Math.random()*2000) );

t2 = new Test Th( “Thread 2″,(int)(Math.random()*2000) );

t3 = new Test Th( “Thread 3″,(int)(Math.random()*2000) );

// Arrancamos los threads

t1.start();

t2.start();

t3.start();

}

}

Page 6: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo

3.3 Creación y Control de Hilos:

En Java, los hilos comparten el mismo espacio de memoria. Incluso comparten gran parte del

entorno de ejecución, de modo que la creación de nuevos hilos es mucho más rápida que la

creación de nuevos procesos. La ventaja que proporcionan los hilos es la capacidad de tener más

de un camino de ejecución en un mismo programa. Así, con un único proceso, ejecutándose una

JVM (Java Virtual Machine), habrá siempre más de un hilo, cada uno con su propio camino de

ejecución.

En cuanto al proceso de creación de hilos, son dos los mecanismos que nos permiten

llevarlo a cabo en Java: implementando la interfaz Runnable, o extendiendo la clase Thread,

esto es, creando una subclase de esta clase.

Lo más habitual es crear hilos implementando la interfaz Runnable, dado que las

interfaces representan una forma de encapsulamiento del trabajo que una clase debe realizar.

Así, se utilizan para el diseño de requisitos comunes a todas las clases que se tiene previsto

implementar. La interfaz define el trabajo, la funcionalidad que debe cubrirse, mientras que la

Page 7: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo

clase o clases que implementan la interfaz realizan dicho trabajo (cumplen esa funcionalidad).

Todas las clases o grupos de clases que implementen una cierta interfaz deberán seguir las

mismas reglas de funcionamiento.

El otro mecanismo de creación de hilos, como ya hemos dicho, consistiría en la creación

previa de una subclase de la clase Thread, la cual podríamos instanciar después.

Por ejemplo,

class Mi Thread extends Thread {

public void run() {

. . .

}

}

se corresponde con la declaración de un clase, Mi Thread, que extiende la clase Thread,

sobrecargando el método Thread.run heredado con su propia implementación.

González et al.

5

Es en el método run donde se implementa el código correspondiente a la acción (la tarea)

que el hilo debe desarrollar . El método run no es invocado directa o explícitamente (a menos

Page 8: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo

que no quieras que se ejecute dentro de su propio hilo). En lugar de esto, los hilos se arrancan

con el método start, se suspenden con el método suspend, se reanudan con el método

resume, y se detienen con el método stop (el cual supone también la muerte del hilo y la

correspondiente excepción Thread Death?), como ya explicaremos en el apartado de Estado y

Control de Hilos. Un hilo suspendido puede reanudarse en la instrucción del método run en la

que fue suspendido.

En el caso de crear un hilo extendiendo la clase Thread, se pueden heredar los métodos y

variables de la clase padre. Si es así, una misma subclase solamente puede extender o derivar

una vez de la clase padre Thread. Esta limitación de Java puede ser superada a través de la

implementación de Runnable. Veamos el siguiente ejemplo:

public class Mi Thread implements Runnable {

Thread t;

public void run() {

// Ejecución del thread una vez creado

}

}

Page 9: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo

En este caso necesitamos crear una instancia de Thread antes de que el sistema pueda

ejecutar el proceso como un hilo. Además, el método abstracto run que está definido en la

interfaz Runnable tiene que implementarse en la nueva clase creada.

La diferencia entre ambos métodos de creación de hilos en Java radica en la flexibilidad con

que cuenta el programador, que es mayor en el caso de la utilización de la interfaz Runnable.

Sobre la base del ejemplo anterior, se podría extender la clase Mi Thread a continuación, si

fuese necesario. La mayoría de las clases creadas que necesiten ejecutarse como un hilo

implementarán la interfaz Runnable, ya que así queda cubierta la posibilidad de que sean

extendidas por otras clases.

Por otro lado, es un error pensar que la interfaz Runnable está realizando alguna tarea

mientras un hilo de alguna clase que la implemente se está ejecutando. Es una interfaz, y como

tal, sólo contiene funciones abstractas (concretamente una única, run), proporcionando tan solo

una idea de diseño, de infraestructura, de la clase Thread, pero ninguna funcionalidad. Su

declaración en Java tiene el siguiente aspecto:

Page 10: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo

package Java.lang;

public interfaz Runnable {

public abstract void run() ;

}

Comentados los aspectos más importantes de la interfaz Runnable, veamos ahora la

definición de la clase Thread, de la cual podemos deducir lo que realmente se está haciendo:

public class Thread implements Runnable {

public void run() {

Java Threads (Hilos en Java)

6

if( tarea != null )

tarea.run() ;

}

…}

Se deduce, por tanto, que la propia clase Thread de Java también implementa la interfaz

Runnable. Observamos que en el método run de Thread se comprueba si la clase con que

Page 11: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo

se está trabajando en ese momento (tarea), que es la clase que se pretende ejecutar como hilo,

es o no nula. En caso de no ser nula, se invoca al método run propio de dicha clase.

Control de un hilo

Arranque de un hilo

En el contexto de las aplicaciones, sabemos que es main la primera función que se invoca tras

arrancar, y por tanto, lógicamente, es el lugar más apropiado para crear y arrancar otros hilos.

La línea de código:

t1 = new Test Th?( “Thread 1″,(int)(Math.random()*2000) );

siendo Test Th una subclase de la clase Thread (o una clase que implemente la interfaz

Runnable) crea un nuevo hilo. Los dos argumentos pasados, sin mayor relevancia, satisfarán

el prototipo del constructor de la clase y se utilizarán para la inicialización del objeto.

Al tener control directo sobre los hilos, tenemos que arrancarlos explícitamente. Como ya se

comentó anteriormente, es la función miembro start la que nos permite hacerlo. En nuestro

ejemplo sería:

t1.start();

Page 12: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo

start, en realidad es un método oculto en el hilo que llama al método run.

Manipulación de un hilo

Si todo fue bien en la creación del objeto Test Th (t1), éste debería contener un hilo, una traza

de ejecución válida, que controlaremos en el método run del objeto.

El cuerpo de esta función miembro viene a ser el cuerpo de un programa como ya los

conocemos. Digamos que es la rutina main a nivel de hilo. Todo lo que queremos que haga el

hilo debe estar dentro del método run. Cuando finalice run, finalizará también el hilo que lo

ejecutaba.

Suspensión de un Hilo

La función miembro suspend de la clase Thread permite tener un control sobre el hilo de

modo que podamos desactivarlo, detener su actividad durante un intervalo de tiempo

indeterminado, a diferencia del uso de la llamada al sistema sleep, que simplemente lleva al

hilo a un estado de “dormido”, y siempre durante un número de milisegundos concreto.

Este método puede resultar útil si, construyendo un applet con un hilo de animación,

queremos permitir al usuario detener (que no finalizar) la animación, hasta que éste decida

Page 13: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo

reanudarla.

Este método no detiene la ejecución permanentemente. El hilo es suspendido

indefinidamente y para volver a activarlo de nuevo necesitamos realizar una invocación a la

función miembro resume.

González et al.

9

Parada de un Hilo

Ya conocemos los métodos de control de hilos que nos permiten arrancarlos, suspenderlos y

reanudarlos. El último elemento de control que se necesita sobre hilos es el método stop,

utilizado para terminar la ejecución de un hilo de forma permanente:

t1.stop();

Señalar que esta llamada no destruye el hilo, sino que detiene su ejecución, y ésta no puede

reanudarse con el método start. Cuando se desasignen las variables que se usan en el hilo, el

objeto hilo (creado con new) quedará marcado para eliminarlo y el garbage collector

(recolector de basura de Java) se encargará de liberar la memoria que utilizaba.

Tiene sentido su utilidad, por ejemplo, en aplicaciones complejas que necesiten un control

Page 14: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo

sobre cada uno de los hilos que se lancen.

Por último, un método de control de hilos que nos permite comprobar si una instancia está

viva (el hilo se ha arrancado y aún no se ha detenido) o no (bien no se arrancó; bien ya finalizó).

Estamos hablando de la función miembro isAlive.

t1.isAlive();

Devolverá true en caso de que el hilo t1 esté vivo, es decir, ya se haya llamado a su

método run y no haya sido parado con un stop ni haya terminado el método run en su

ejecución. En otro caso, lógicamente, devolverá false.

3.3.1 Atributo de Hilo:

Cada thread cuenta con diferentes propiedades que lo hacen unico. Se adopta un enfoque orientado a objetos con respecto a la representacion y asignacion de propiedades. Bajo este paradigma cada thread cuenta con un objeto atributo asociado a varios threads. Los objetos atributos son del tipo:

pthread_attr_t

Los atributos/propiedades de un thread varian de una implementacion a otra. Sin embargo a manera general los atributos que denen a un thread son:

Estado de espera: permite que otros threads esperen por la terminacion de un thread en especial.

Direccion de stack: apuntador al inicio del stack del thread

Page 15: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo

Tamano de la direccion: longitud del stack del thread.

Alcance (scope): dene quien controla la ejecucion del thread: el proceso o el nucleo del sistema operativo.

Herencia: los parametros de calendarizacion son heredados o denidos localmente.

Politica de calendarizacion: la politica que va a definir que proceso se va a ejecutar y en que instante.

{

FIFO

{

Round-robin

{

Prioridad: un valor de prioridad alto corresponde a una mayor prioridad.

Es posible modicar varios de estos atributos a traves de diferentes llamadas de sistema.

Lafuncion pthread_attr_init

asigna los atributos de default a los threads y la funcion

pthread_attr_destroy hace que el valor del objeto atributo sea invalido

3-3-2 Creación He Inicialización de Hilo:

Antes de poder usar cualquier función de manejo de hilos, hay que preparar el sistema para ejecutar estas operaciones, es decir, es necesario inicializar el sistema de hilos, nada más sencillo.

Page 16: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo

Void g_thread_init (G Thread Functions? *vtable );

En la mayoría de las ocasiones bastará con que el parámetro pasado al sistema de hilos sea nulo, de esta forma G Lib? se encargará de buscar los parámetros más apropiados.

Es importante no llamar a esta función más de una vez pues, si esto sucediese, la ejecución de nuestro programa sería abortada. Para evitar esto la forma más sencilla es hacer:

if (!g_thread_supported ())

g_thread_init (NULL);

Después, el sistema estará listo para realizar cualquier operación que requiera el uso de hilos. Para empezar, se creará un hilo:

G Thread? *hilo: hilo = g_thread_create (funcion_hilo, NULL, FALSE, NULL);

A partir de este punto, el procedimiento funcion_hilo se ejecutará en un hilo diferente, el programa continuará su ejecución normal y, en paralelo a él, se ejecutará esta función.

3.3.3 Aranque de Hilos:

En el contexto de las aplicaciones, sabemos que es main la primera función que se invoca tras

arrancar, y por tanto, lógicamente, es el lugar más apropiado para crear y arrancar otros hilos.

La línea de código:

t1 = new Test Th?( “Thread 1″,(int)(Math.random()*2000) );

Page 17: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo

siendo Test Th una subclase de la clase Thread (o una clase que implemente la interfaz

Runnable) crea un nuevo hilo. Los dos argumentos pasados, sin mayor relevancia, satisfarán

el prototipo del constructor de la clase y se utilizarán para la inicialización del objeto.

Al tener control directo sobre los hilos, tenemos que arrancarlos explícitamente. Como ya se

comentó anteriormente, es la función miembro start la que nos permite hacerlo. En nuestro

ejemplo sería:

t1.start();

start, en realidad es un método oculto en el hilo que llama al método run

3.3.4 Manipulación de Hilos:

Si todo fue bien en la creación del objeto Test Th? (t1), éste debería contener un hilo, una traza

de ejecución válida, que controlaremos en el método run del objeto.

El cuerpo de esta función miembro viene a ser el cuerpo de un programa como ya los

conocemos. Digamos que es la rutina main a nivel de hilo. Todo lo que queremos que haga el

hilo debe estar dentro del método run. Cuando finalice run, finalizará también el hilo que lo

Page 18: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo

ejecutaba.

3.3.5 Suspensión de Hilos:

La función miembro suspend de la clase Thread permite tener un control sobre el hilo de

modo que podamos desactivarlo, detener su actividad durante un intervalo de tiempo

indeterminado, a diferencia del uso de la llamada al sistema sleep, que simplemente lleva al

hilo a un estado de “dormido”, y siempre durante un número de milisegundos concreto.

Este método puede resultar útil si, construyendo un applet con un hilo de animación,

queremos permitir al usuario detener (que no finalizar) la animación, hasta que éste decida

reanudarla.

Este método no detiene la ejecución permanentemente. El hilo es suspendido

indefinidamente y para volver a activarlo de nuevo necesitamos realizar una invocación a la

función miembro resume.

Page 19: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo

3.3.6 Parada de Hilo:

Suspensión de un Hilo El último elemento de control que se necesita sobre los hilos de ejecución es el método stop(). Se utiliza para terminar la ejecución de un hilo: t1.stop();

Esta llamada no destruye el hilo, sino que detiene su ejecución. La ejecución no se puede reanudar ya con t1.start(). Cuando se desasignen las variables que se usan en el hilo, el objeto Thread (creado con new) quedará marcado para eliminarlo y el garbage collector se encargará de liberar la memoria que utilizaba.

Si se necesita, se puede comprobar si un hilo está vivo o no; considerando vivo un hilo que ha comenzado y no ha sido detenido. t1.isAlive();

Este método devolverá true en caso de que el hilo t1 esté vivo, es decir, ya se haya llamado a su método run() y no haya sido parado con un stop() ni haya terminado el método run() en su ejecución.

En el ejemplo no hay problemas de realizar una parada incondicional, al estar todos los hilos vivos. Pero si a un hilo de ejecución, que puede no estar vivo, se le invoca su método stop(), se generará una excepción. En este caso, en los que el estado del hilo no puede conocerse de antemano es donde se requiere el uso del método isAlive().

3.4 Sincronización de Hilos:

El problema de la sincronización de hilos tiene lugar cuando varios hilos intentan acceder al

mismo recurso o dato. A la hora de acceder a datos comunes, los hilos necesitan establecer

Page 20: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo

cierto orden, por ejemplo en el caso del productor consumidor. Para asegurarse de que hilos

concurrentes no se estorban y operan correctamente con datos (o recursos) compartidos, un

sistema estable previene la inanición y el punto muerto o interbloqueo. La inanición tiene lugar

cuando uno o más hilos están bloqueados al intentar conseguir acceso a un recurso compartido

de ocurrencias limitadas. El interbloqueo es la última fase de la inanición; ocurre cuando uno o

más hilos están esperando una condición que no puede ser satisfecha. Esto ocurre muy

frecuentemente cuando dos o más hilos están esperando a que el otro u otros se desbloquee,

respectivamente.

A continuación se presenta un ejemplo, el problema del Productor/Consumidor, con la

intención de explicar de una forma más práctica el concepto y las situciones de sincronización

de hilos.

3.4.1 Mutex

Mutex es la abreviatura de “mutual exclusión”, es decir, exclusión mutua. Las variables Mutex son la forma más común de implementar la sincronización de threads y de proteger datos compartidos cuando acontecen multitud de escrituras sobre esos datos compartidos.

Page 21: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo

Una variable Mutex actúa como un candado protegiendo los datos o recursos. El concepto básico de Mutex en Pthreads es que sólo un thread puede cerrar el candado en un determinado instante. Incluso si varios threads intentan cerrar el mismo candado sólo uno saldrá victorioso. Ningún otro thread podrá poseer ese Mutex hasta que el que lo cerró lo abra. Es decir, con esto conseguimos que los threads se turnen para acceder a datos protegidos o compartidos.

Los Mutex pueden ser usados para prevenir “condiciones de carrera”. Este es un ejemplo de una “condición de carrera” en una transacción de un banco.

Una típica secuencia en el uso de un Mutex es:

1. Crear e inicializar la variable Mutex.

2. Varios threads intentan bloquear el Mutex.

3. Sólo uno lo hace y es el poseedor del Mutex.

4. El poseedor del Mutex realiza un conjunto de acciones.

5. El poseedor del Mutex desbloquea el Mutex.

6. Otro thread toma el Mutex y repite el proceso.

7. Finalmente el Mutex es destruido.

Cuando varios threads compiten por un Mutex, los perdedores se bloquean hasta que el ganador desbloquea el Mutex.

3.4.2 Semáforos:

Los semáforos se pueden considerar primitivas de bajo nivel en comparación con otros modelos de paso de mensajes. Debido a su dificultad de utilización, resultan poco apropiados para utilizar en los programas, por lo que se debería limitar a módulos muy definidos.

Page 22: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo

Tipos de semáforos

Los semáforos operan con enteros no negativos. En función del rango de valores posibles, hay dos tipos de semáforos:

Binarios: toman valores 0 y 1

Generales: toman los valores mayores de 0

Los lenguajes de programación normalmente trabajan con semáforos generales. En caso de que no fuera así, se podrían implementar con semáforos binarios.

3.4.3 Barreras Barier:

Enunciado. Un proceso crea N hilos. El comportamiento de cada uno consiste en la ejecución de un bucle con tres partes:

A

BARRERA

B

En cada iteración del bucle los hilos ejecutarán A sin realizar ninguna sincronización; a continuación todos ellos esperan a que el resto llegue a la BARRERA. Una vez que todos han llegado a la barrera (todos han ejecutado A), continúan ejecutando B y el bucle se repite.

Salidas. Cada hilo deberá informar del número de iteración junto con el punto del bucle que acaba de ejecutar.

Finalización. Ejecutar la iteración un cierto número de veces

Esquema del problema

Muchos problemas de cálculo se pueden resolver de acuerdo al siguiente esquema:

Page 23: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo

Ejemplos:

–procesamiento de imágenes

–funciones definidas sobre mallas de puntos

–resolución de sistemas de ecuaciones

–problemas de optimización, etc.

La ejecución de “esperar al resto de procesos” es una sincronización, este tipo se denomina “sincronización por barrera”.

Page 24: gemeher.files.wordpress.com€¦  · Web viewComo Word, cada aplicación ... Entornos tales como el de Macintosh de Apple, ... Este método devolverá true en caso de que el hilo