multi tare a con hilos en windows

28
  Multitarea con hilos en Windows Un hilo es un camino de ejecución mediante un programa. En un programa multihilo, cada hilo tiene su propia pila y funciona independientemente de otros hilos que corren dentro del mismo programa. MFC distingue entre UI hilos (hilos de interfaz de usuario), que tienen una bomba mensaje y suelen realizar tareas sobre la interfaz de usuario, e hilos de proceso, que no lo hacen. NOTA: Cualquier aplicación siempre tiene al menos un hilo, que es el hilo principal del programa. Un hilo es la unidad más pequeña de ejecución, mucho más pequeños que un proceso. Generalmente cada aplicación corriendo en un sistema es un proceso. Si inicia la misma solicitud (por ejemplo, Notepad) dos veces, habrá dos procesos, uno para cada instancia. Es posible que varios instancias de un aplicación compartan un mismo proceso; por ejemplo, si usted elija File, New Windo w en Internet Explorer, hay dos a plicaciones en la barra de tareas, y comparten un proceso. La consecuencia lamentable es que si una instancia cuelga, todas ellas lo hacer. Para crear un hilo trabajador (o de proceso) utilizando MFC, todo lo que se tiene que hacer es escribir una función que se desee correr en paralelo con el resto de su aplicación. Luego, se llame a AfxBeginThread() para iniciar un hilo que ejecutará su función. El hilo permanece activo mientras la función se esté ejecutando: Cuando el hilo termina, es destruido. Un ejemplo de llamada a AfxBeginThread() se ve así: AfxBeginThread(ProcName, param, priority); En la línea anterior, Proc_ame es el nombre de la función hilo, param es cualquier valor de 32-bit que desea pasar al hilo, y priority es la prioridad del hilo, la cual es representada por un número de constantes predefinidas. En el Cuadro 27.1 muestra las posibles constantes y sus descripciones.

Upload: lalo-larios

Post on 07-Jul-2015

157 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 1/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

Multitarea con hilos en WindowsUn hilo es un camino de ejecución mediante un programa. En un programa multihilo,cada hilo tiene su propia pila y funciona independientemente de otros hilos que correndentro del mismo programa. MFC distingue entre UI hilos (hilos de interfaz deusuario), que tienen una bomba mensaje y suelen realizar tareas sobre la interfaz deusuario, e hilos de proceso, que no lo hacen.

NOTA:Cualquier aplicación siempre tiene al menos un hilo, que es el hilo principal delprograma.Un hilo es la unidad más pequeña de ejecución, mucho más pequeños que unproceso.Generalmente cada aplicación corriendo en un sistema es un proceso. Si inicia lamisma solicitud (por ejemplo, Notepad) dos veces, habrá dos procesos, uno para cadainstancia.Es posible que varios instancias de un aplicación compartan un mismo proceso; por

ejemplo, si usted elija File, New Window en Internet Explorer, hay dos aplicaciones enla barra de tareas, y comparten un proceso. La consecuencia lamentable es que siuna instancia cuelga, todas ellas lo hacer.Para crear un hilo trabajador (o de proceso) utilizando MFC, todo lo que se tiene quehacer es escribir una función que se desee correr en paralelo con el resto de suaplicación. Luego, se llame a AfxBeginThread() para iniciar un hilo que ejecutará sufunción. El hilo permanece activo mientras la función se esté ejecutando: Cuando elhilo termina, es destruido. Un ejemplo de llamada a AfxBeginThread() se ve así:

AfxBeginThread(ProcName, param, priority);

En la línea anterior, Proc_ame es el nombre de la función hilo, param es cualquier

valor de 32-bit que desea pasar al hilo, y priority es la prioridad del hilo, la cual esrepresentada por un número de constantes predefinidas. En el Cuadro 27.1 muestralas posibles constantes y sus descripciones.

Page 2: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 2/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

NOTA: La prioridad de un hilo, determina su frecuencia al toma el control del sistema,en relación a los otros hilos en ejecución. Generalmente, a mayor prioridad, mástiempo el flujo obtiene el control. La mayor prioridad esta dada por la constante deTHREAD_PRIORITY_TIME_CRITICAL.

Desarrollemos una aplicación simple. Para probar lo dicho hasta aquí.1. Inicia una aplicación Visual Asistida con nombre Thread. De un solo documento.

2. En el paso 4 del asistente desmarca todas las opciones. Los demás pasos quedancon los valores por defecto.

Page 3: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 3/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

3. Usando el editor de recursos selecciona el menú y en él a IDR_MAINFRAME de laaplicación, para adicionar un nuevo comando llamado Start Thread con unidentificador del comando de ID_STARTTHREAD, y define su propiedad ToolTipcomo se muestra abajo.

4. Utiliza ClassWizard para asociar el comando IDC_IniciarHilo con la función derespuesta al mensaje OnIniciarHilo(). Asegurándote de que la clase CThreadViewesta seleccionada en la caja Class Name antes de adicionar la función. Observa lafigura abajo.

Page 4: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 4/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

5. Acepta el nombre sugerido para la función y haz clic en el botón Edit Code yagrega las siguientes líneas a la nueva función OnIniciarHilo(), como se muestra+abajo:

void CThreadView::OnIniciarHilo()

{ // TODO: Add your command handler code hereHWND hWnd = GetSafeHwnd();

 AfxBeginThread(ThreadProc, hWnd, THREAD_PRIORITY_NORMAL);

6. Este código llamar a una función denominada ThreadProc dentro de un hilotrabajador de su propiedad. A continuación, añade ThreadProc, mostrado en ellistado A1, al archivo ThreadView.cpp, colocándola justo antes de la funciónOnIniciarHilo. O bien al inicio del archivo THreadView después del estatuto EndIF.

Nota que ThreadProc() es una función global y no una función miembro de la claseCThreadView, siempre en el archivo de implementación de la clase vista.

//Listado de la función - ThreadProc()UINT ThreadProc(LPVOID param){

::MessageBox((HWND)param, "Thread activated.","Thread", MB_OK);return 0;

}

Esta función hilada (rosca, o activa en hilo pues) no hace mucho, sólo informa que se

inició el hilo. La función MessageBox() de SDK es muy similar AfxMessageBox(), perocomo ésta no es una función miembro de una clase derivada de CWnd, no se puedeusar AfxMEssageBox().

Nota: Los dobles dos puntos (::) al frente de un nombre de función indican unallamada a una función global, en lugar de una miembro función de una clase MFC.Para programadores Windows, esto generalmente significa una llamada a API o SDK.Por ejemplo, dentro de una clase ventana MFC, se puede llamar MessageBox("Hi,There!") para mostrar Hi, there! Al usuario. Esta forma de MessageBox() es unafunción miembro de la clase Window MFC. Para llamar a la versión original deWindows, se debe escribir algo como ::MessageBox(0, "Hi, There!", "Mensaje",MB_OK). Nota que los dos puntos en frente de la función nombre y los argumentos

adicionales.Ahora cuando ejecutes el programa Thread, aparece la ventana principal. Seleccioneel comando hilo, Iniciar Hilo, y el sistema inicia el hilo representado por la funciónThreadProc() y muestra un cuadro de mensaje, como se muestra en la figura abajo.

Page 5: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 5/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

Hasta aquí la aplicación Thread que muestra como activar un hilo.

Entendiendo la comunicación de hilos

Generalmente un hilo secundario realiza algún tipo de tarea para el programaprincipal, lo que implica que es necesario que haya un canal de comunicación entre elprograma (que también es un hilo) y su o sus hilos secundarios. Hay varias manerasde lograr estas comunicaciones entre tareas:

• Variables globales• Οbjetos event • Mensajes definidos por el usuario.

Se da a continuación un ejemplo de cada una de ellas.

Comunicación con variables globales (aplicación --> Thread)

Supongamos que desea que su programa principal sea capaz de detener el hilo. Senecesita una forma de decirle al hilo cuando debe detenerse. Un método consiste enestablecer una variable global y entonces el hilo debe vigilar la variable globalesperando un valor que sea la señal para detenerse. Esto se debe al hecho de quelos hilos comparten el mismo espacio de direcciones, tienen por lo tanto las mismasvariables globales. Para ver cómo funciona esta técnica, modifiquemos la aplicaciónThread como sigue:

1. Utilizar el recurso editor para agregar el comando Stop Thread para detener el hilodesde la aplicación Thread, modifica el menú. Dar a este nuevo comando elidentificador ID_DetieneHilo, como se muestra en la figura abajo:

Page 6: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 6/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

2. Usando ClassWizard, asocia el comando ID_STOPTHREAD con la función derespuesta al mensaje OnDetieneHilo, como se muestra en la figura abajo.

Asegúrate que esté la clase CThreadView seleccionada en la caja de Class Nameantes de agregar la función. Adiciona la siguiente línea a la función OnDetieneHilodebajo de la línea //TODO:

threadController = 0;

Esto implica que la nueva variable global debe declararse.

Page 7: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 7/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

3. Agregue la línea siguiente al inicio del archivo ThreadView.cpp, justo después dela directiva #endif:

volatile int threadController;

Debe verse así:

La palabra volátil significa que se espera que esta variable sea cambiada desde fuerade un hilo que utiliza. La palabra volatile pide que el compilador no cache la variable

en un registro o de cualquier manera cuentan con el valor permanecer sin cambiossólo porque el código en un hilo no parece cambiar.

4. Agregar la siguiente línea a la función OnIniciarHilo(), antes de las dos líneas quese añadieron antes:

threadController = 1;

Se ve así:

void CThareadView::OnIniciarHilo()

{ // TODO: Add your command handler code hereHWND hWnd = GetSafeHwnd();AfxBeginThread(ThreadProc, hWnd, THREAD_PRIORITY_NORMAL);

threadController = 1;

}

5. Por ahora, tal vez, se adivine que el valor de threadController determina si el hilocontinuará. Sustituir la función ThreadProc() con la mostrada en el listado A2.

// Listado A2 La nueva función ThreadProc()UINT ThreadProc(LPVOID param){

::MessageBox((HWND)param, "Thread activated.","Thread", MB_OK);while (threadController == 1){

;}

Page 8: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 8/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

::MessageBox((HWND)param, "Thread stopped.", "Thread", MB_OK);return 0;

}

Ahora el hilo primario muestra un cuadro de mensaje, diciéndole al usuario que el hiloestá comenzando. Entonces el ciclo While continúa para comprobar la variable globalthreadController, esperando que su valor cambie a 0. Aunque este ciclo While estrivial, es aquí donde se tendría que ubicar el código que realice cualquier tarea quese desee que el hilo lleve a cabo, asegurándose no implementar cosas durantedemasiado tiempo antes de la recomprobación del valor de threadController.

6. Para comprobar. Compila y corre el programa, y elige el comando Iniciar Hilo delmenú Thared para iniciar el hilo secundario. Al hacerlo, un cuadro de mensajeaparece, diciéndole que el nuevo hilo se inició. Para detener el hilo, seleccione elcomando Stop Hilo. De nuevo, un cuadro de mensaje aparece, esta vez diciéndoleque el hilo se ha detenido.

PRECAUCIÓN: Utilizar variables globales para comunicarse entre hilos es, por decir lomenos, un enfoque rudimentario para la comunicación con hilos y puede ser una técnicapeligrosa si no se sabe cómo maneja C++ las variables de un asamblea-a-nivel lenguaje.Existen otras técnicas de comunicación entre hilos que son más seguras y elegantes.

Page 9: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 9/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

Comunicación mediante mensajes definidos por el usuario

Comunicarse con Mensajes definidos por el usuario es un simple, aunque es unmétodo poco sofisticado para establecer comunicar entre el programa principal y sushilos. La pregunta aquí es:

¿Cómo puede un hilo comunicarse con el programa principal?

El método más fácil para cumplir esta comunicación es incorporar en el programa,mensajes Windows definidos por el usuario.

Para poder establecer la comunicación entre hilos se requieres al menos dos pasos,se presentan éstos a continuación:

PRIMERO: Definir un mensaje de usuario, lo cual es un paso muy fácil, requieredeclarar una constante con el número a representar al mensaje, observa la líneasiguiente:

Const WM_USERMSG =WM_USER +100;

Podemos observar la constante WM_USER, que es definida por Windows paramanejar los primeros números de mensaje disponibles para usuario. Debido al hechode que otras partes del programa puedan definir otros mensajes de usuario para suspropios propósitos.

SEGUNDO: Después de definir el mensaje, se realiza una llamada a la función básica::PostMessage() desde el hilo para enviar el mensaje al programa principal cuandosea necesario. Se debe ver así:

::PostMessage((HWND) param, WM_USERMSG, 0, 0);

Donde los cuatro argumentos de ::PostMessage() son, en su orden:

a) el manejador de la ventana (param) a la cual el mensaje debe ser enviado.b) el identificador del mensaje (en este caso WM_USERMSG), y los parámetros delmensaje:

c) WPARM yd) LPARAM

Los cuales por el momento no tienen importancia para nuestros propósitos.

Page 10: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 10/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

Ejemplo de comunicación de los hilos al programa principal(aplicación: Thread en Comunica1)

Para mostrar la respuesta de los hilos al programa principal, usaremos le mismoprograma anterior, es decir modificamos la aplicación Thread anterior incluyendo lossiguientes pasos para implementar la asignación de mensajes de usuario entre hilos yla aplicación:

1. Agregar la siguiente línea en la parte superior del archivo de encabezadoThreadView.h justo antes del inicio de la declaración de la clase:

const WM_THREADENDED =WM_USER +100;

2. Todavía en el archive de encabezado, agrega la siguiente línea al mapa demensajes, justo después del comentario //{{AFX_MSG(CThreadView) y antes

de DECLARE_MESSAGE_MAP:

afx_msg LONG OnThreadended(WPARAM wParam, LPARAM lParam);

3. Cambiate al archivo ThreadView.cpp y agrega la siguiente línea en el mapa de mensajes de la

clase, asegurándote de colocarla justo después del comentario: }}AFX_MSG_MAP

ON_MESSAGE(WM_THREADENDED, OnThreadended)

4. Reemplaza la function ThreadProc() con el listado abajo:

 // Listado A3 Nueva version de la función ThreadProcUINT ThreadProc(LPVOID param){

::MessageBox((HWND)param, "Thread activated.","Thread", MB_OK);while (threadController == 1){

;}::PostMessage((HWND)param, WM_THREADENDED, 0, 0);return 0;

}

5. Agrega la función que se muestra en el listado A4 al finaldel archive ThreadView.cpp

//Listing A4 CThreadView::OnThreadended()LONG CThreadView::OnThreadended(WPARAM wParam, LPARAMlParam)

Page 11: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 11/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

{AfxMessageBox("Thread ended.");return 0;

}

Cuando ejecute la nueva versión del programa Thread, selecciona el comando StartThread para iniciar el hilo. Cuando lo haga, un cuadro de mensaje aparece, diciéndoleque el flujo ha comenzado. Para poner fin al hilo, seleccione el comando Stop Thread.Al igual que con la versión anterior del programa, un cuadro de mensaje aparece,Diciéndole que el flujo ha terminado.Al igual que con la versión anterior del programa, un cuadro de mensaje aparece,diciéndole que el flujo ha terminado. Aunque esta versión de la aplicación Threadparece correr idéntica a la versión anterior, existe una sutil diferencia.Ahora el programa muestra el cuadro de mensaje que señala el final del hilo en elprograma principal más que desde el interior del hilo. El programa puede hacer estoporque, cuando el usuario selecciona el comando Stop Thread, el hilo envía unmensaje WM_THREADENDED al programa principal. Cuando el programa recibe ese

mensaje, muestra una caja de mensaje final.

Page 12: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 12/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

COMUNICACIÓN MEDIANTE OBJETOS EVENT 

Un método un poco mas sofisticado de comunicación entre hilos es el de objetos deevento (event objects), el cual bajo MFC se representa por la clase CEvent. Un objetoevento se puede encontrarse en uno de dos posibles estados: señalado (signaled) ono_señalado (nonsignaled). Los hilos pueden estar pendientes de los eventos quepuedan señalarlos y así desarrollar las operaciones asignadas en el momentoadecuado. Crear un objeto evento es tan fácil como declarar una variable global, se veasí:

CEvent iniciaHilo; // inicialmente es no-señalado

Aunque el constructor de la clase CEvent tiene una serie de argumentosopcionales, generalmente se emplea la creación por defecto del objeto, como semuestra en la línea anterior de código. En la creación, el objeto de evento seencuentra en su estado no-señalado. Para evocar el evento, se llama a la función

miembro SetEvent() del objeto. Se ve así:

iniciaHilo.SetEvent();

Donde iniciarHilo es un objeto de clase CEvent. Después de que la líneaanterior se ejecuta, el objeto de evento iniciarHilo estará en su estadoseñalado. Un hilo debe esperar por esta señal para que el hilo sepa quedebe iniciar su trabajar. Aquí una pregunta válida sería:

¿Cómo hacer que un hilo espere por una señal?

La respuesta es: Llamando a la función WaitForSingleObject() de la API deWindows, observa el ejemplo en la siguiente línea:

::WaitForSingleObject(iniciaHilo.m_hObject, INFINITE);

Como se puede observar, son dos los argumentos de esta función:

• El manejador de eventos para el cual comprueba (almacenado en los datosmiembro del objeto de ejemplo m_hObject).

• El periodo de tiempo que la función debe esperar por el evento. La constante

predefinida INFINITE establece que la función no regrese hasta que el eventosea señalado.

En otras palabras, si se coloca la línea anterior de código al inicio de su hilo, elsistema suspende al hilo hasta que el evento sea señalado.Aunque usted comience la ejecución del hilo, éste es suspendido hasta que suceda loque debe suceder. Cuando el programa está listo para que el hilo cumpla su deber, sedebe llamar a la función SetEvent(), descrito anteriormente.

Page 13: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 13/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

Cuando el hilo ya no está suspendido, puede desempeñar su trabajo. Sin embargo, sise requiere marcar el final del hilo del programa principal, el hilo debe vigilar a queeste próximo acontecimiento sea señalizado. El hilo puede hacer esto vigilando en elentorno para el evento.Para sondear el evento, se realiza nuevamente un llamamiento a

WaitForSingleObject(), sólo esta vez se da la función un tiempo de espera de 0, comose observa enseguida:

::WaitForSingleObject(threadend.m_hObject, 0);

En este caso, si WaitForSingleObject() devuelve la constante WAIT_OBJECT_0, elevento ha sido señalado. De lo contrario, el evento todavía es noseñalado(nonsignaled).

Para observar mejor cómo trabaja el objetos event, sigue estos pasos para modificarnuevamente la aplicación Hilos (en la carpeta comunica2):

1. Agrega la siguiente línea al inicio del archivo ThreadView.cpp, justodespués de la línea #include "ThreadView.h":

#include "afxmt.h"

Debe verse así:

2. Agrega las siguientes líneas cerca del inicio del archive ThreadView.cpp,después de la linea volatile int threadController que fue colocada conanterioridad:

CEvent threadStart;CEvent threadEnd;

3. Elimine la línea volatile int threadController; del archivo.4. Remplace la función ThreadProc() como se muestra en el siguiente

listado.

Page 14: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 14/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

UINT ThreadProc(LPVOID param){

::WaitForSingleObject(threadStart.m_hObject,INFINITE);::MessageBox((HWND)param, "Thread activated.","Thread", MB_OK);

BOOL keepRunning = TRUE;while (keepRunning){

int result =::WaitForSingleObject(threadEnd.m_hObject, 0);if (result == WAIT_OBJECT_0)

keepRunning = FALSE;}::PostMessage((HWND)param, WM_THREADENDED, 0, 0);return 0;

}

5. Remplace todo el código en la function OnIniciarHilo() con la siguiente

línea:threadStart.SetEvent();

Se debe ver así:

void CThareadView::OnIniciarHilo(){

// TODO: Add your command handler code here

threadStart.SetEvent(); }

6. Remplace el código en la función OnDetenerHilo() con la línea siguiente:threadEnd.SetEvent();

Se debe ver así:void CThareadView::OnDetieneHilo(){

 // TODO: Add your command handler code herethreadEnd.SetEvent();

}

7. Empleando ClassWizard agrega la function OnCreate() que controla elmensaje WM_CREATE, asegurandose que se que esta seleccionada laclase CThreadView en la caja de texto Class Name antes de agregar lafunción.

Page 15: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 15/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

8. Agrega las siguientes líneas en la función OnCreate(). Seleccionando elmensaje WM_CREATE. Observa abajo la figura.

 // Se crea el hilo desde la creación de la aplicación.HWND hWnd = GetSafeHwnd();AfxBeginThread(ThreadProc, hWnd);

Se debe ver así:

int CThareadView::OnCreate(LPCREATESTRUCT lpCreateStruct){if (CView::OnCreate(lpCreateStruct) == -1)

return -1;

// TODO: Add your specialized creation code here// Se crea el hilo desde la creación de la aplicación.HWND hWnd = GetSafeHwnd();

 AfxBeginThread(ThreadProc, hWnd);

return 0;}

Otra vez, esta nueva versión del programa parece correr al igual que la versiónanterior. Sin embargo, el programa está utilizando tanto objetos event, además demensajes de Windows definidos por el usuario, para establecer la comunicación entreel programa principal y el hilo. Sin meterse en pesados problemas con variablesglobales.

Una gran diferencia de las versiones anteriores del programa es que el hilosecundario es iniciado en la función OnCreate(), que es llamada cuando la primeraaplicación se ejecuta y se crea la vista. Sin embargo, debido a que la primera línea de

Page 16: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 16/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

la función hilo es el llamamiento a WaitForSingleObject(), el hilo inmediatamentesuspende su ejecución y espera que el evento threadStart sea señalado.

Cuando el objeto event de threadStart es señalado, el hilo es libre de mostrar elcuadro de mensaje y luego entra al ciclo While, donde se dan las consultas de los

objetos evento de threadEnd.

El ciclo while se continúa ejecutando hasta que el evento threadEnd sea señalado,momento en que el hilo envía el mensaje WM_THREADENDED al programa principaly las salidas. Debido a que el hilo se inició en OnCreate(), después de que el hilotermina, no puede ser reiniciado.

Page 17: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 17/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

USANDO SINCRONIZACIÓN DE HILOS

Utilizando la Sincronización de Hilo podemos afrontar algunos problemasinteresantes. Ahora la pregunta es:

¿Cómo impedir que dos hilos accedan a los mismos datos al mismotiempo?

Por ejemplo, un hilo está en el momento de tratar de actualizar un conjunto de datoscuando otro hilo intenta leer esos datos, el segundo hilo casi seguramente leerá datoscorruptos porque sólo algunos de los datos se habrán actualizado.

Al hecho de tratar de mantener hilos trabajando juntos adecuadamente, se le llamasincronización de hilos . Los eventos de objeto, acerca de los cuales acabamos deaprender, son una forma de sincronización de hilos. En esta sección, aprenderemosotros métodos de sincronización de hilos, tales como:

•  secciones críticas •  exclusión mutua•  semáforos

Estos métodos nos permiten, al usarlos, que la programación de hilos sea aún mássegura.

SECCIONES CRÍTICAS

Se denomina sección crítica, en programación concurrente, a la porción de códigode un programa de computadora el cual accede a un recurso compartido (ya seaestructura de datos o dispositivo) que no debe de ser accedido por más de un hilo enejecución. La sección crítica por lo general termina en un tiempo determinado y el hilo,proceso o tarea sólo tendrá que esperar un período determinado de tiempo paraentrar. Se necesita de un mecanismo de sincronización en la entrada y salida de lasección crítica para asegurar la utilización exclusiva del recurso, por ejemplo unsemáforo.Las Secciones Críticas son una forma fácil para garantizar que sólo un hilo a la vezpueda acceder a una serie de datos. Cuando se usa una sección crítica, se debe daral hilo un objeto que habrá de compartir.Cualquiera hilo que posea el objeto sección-crítica tiene acceso a los datosprotegidos.Otros hilos tienen que esperar hasta que el primer hilo libere la sección-crítica,después de lo cual otro hilo puede tomar la sección-crítica y acceder a los datos a suvez.Debido a que los datos protegidos están representados por un solo objeto sección-crítica y porque sólo un hilo puede poseer la sección-crítica en un momento dado, losdatos protegidos no podrán ser accedidos nunca por más de un único hilo en un

Page 18: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 18/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

momento dado. Para crear un objeto sección-crítica en un programa MFC, se debecrear una instancia de la clase CCriticalSection, se ve así:

CCriticalSection sectionCritical;  // define un objeto clase CCriticalSection 

Entonces, cuando el código del programa esté cerca de acceder a los datos que sequieren proteger, se debe llamar a la función miembro Lock(), del objeto, se ve así:

sectionCritical.Lock();

Si otro hilo o flujo sin la sección crítica, Lock() da el objeto al llamar al hilo. Ese hilopueda acceder a los datos protegidos, después de lo cual se invoca a la funciónmiembro Unlock() del objeto sección-crítica:

SectionCritical.Unlock();

Unlock()libera la propiedad del objeto sección-crítica- para que otro flujo puede

tomarlo y acceder a los datos protegidos.La mejor manera de aplicar algo como secciones crítica es construir los datos que sedesean proteger dentro de una clase hilo-seguro. Cuando se hacer esto, ya no hay deque preocuparse por la sincronización de hilos en el programa principal; la clasemaneja todo para nosotros. Como ejemplo, observa el siguiente listado, que es elarchivo de encabezado por una clase hilo-seguro.

 // Listado A#include "afxmt.h"class CCountArray{private:

int array[10];CCriticalSection criticalSection;public:

CCountArray() {};~CCountArray() {};void SetArray(int value);void GetArray(int dstArray[10]);

};

El archivo de cabecera empieza la inclusión de la cabecera MFC archivo, afxmt.h, queda el acceso al programa de la CCriticalSection clase. Dentro de la clase CCountArraydeclaración, el archivo declara un vector de 10 elemento enteros, que es lainformación que la sección crítica protege, y declara el objeto sección-crítica-, aquí

llamada criticalSection. Los miembros públicos de la clase CCountArray, incluyenconstructor y destructor habituales, así como las funciones de asignación y lectura delvector.El listado abajo es el archivo de aplicación de la clase CCountArray. Observa que, encada función miembro, la clase tiene cuidado de bloquear y desbloquear el objetosección-crítica. Esto significa que cualquier flujo puede llamar a esas funcionesmiembro sin preocuparse por la sincronización de hilos. Por ejemplo, si el hilo 1 llama

Page 19: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 19/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

a SetArray(), la primera acción que SetArray() realiza es llamar criticalSection.Lock(),lo cual da el objeto crítica-sección al hilo 1.Se completa el ciclo for cuando se ejecuta, sin ningún temor de ser interrumpido porotro hilo. Si el hilo 2 pide SetArray() o GetArray(), el llamamiento acriticalSection.Lock() suspende al hilo 2 hasta que el hilo 1 libere el objeto

seccióncritica, que lo hace cuando SetArray() finaliza para el bucle y ejecuta la líneacriticalSection.Unlock(). Entonces el sistema activa el hilo 2 y le da el objetocriticalSection. De esta forma, todos los hilos tienen que esperar ordenadamente suoportunidad de acceder a los datos guardados.

 //Listado B#include "stdafx.h"#include "CountArray.h"void CCountArray::SetArray(int value){

criticalSection.Lock();for (int x=0; x<10; ++x)

array[x] = value;criticalSection.Unlock();}void CCountArray::GetArray(int dstArray[10]){

criticalSection.Lock();for (int x=0; x<10; ++x)

dstArray[x] = array[x];criticalSection.Unlock();

}

Practica Sincronía mediante Secciones criticas ()

Ahora que usted ha tenido una oportunidad de ver a qué se parece una clase hilo-safe(hilo-seguro o sincronizado), es hora de poner la clase a trabajar. Siga los pasossiguientes, que modifican la aplicación Thread después de probar la comunicaciónmediante objetos Event, esta vez para poner a prueba la clase CCountArray en formasegura mediante sincronización usando el método secciones críticas. Inicia en laversión de Thread de la carpeta Inicio en Sincronia1, una vez abierto este proyecto,inicia la práctica actual. Para ello:

1. Desde File, agrega al proyecto usando New para agregar el archivo deencabezado llamándolo CountArray.h, definiendo como su contenido el listado A.

2. De la misma forma incluye un archivo fuente llamado CountArray.cpp. Define

como su contenido el listado B.3. Cambie a ThreadView.cpp y añade la siguiente línea cerca de la cima del archivo,después de la línea #include "afxmt.h", la cual se coloco previamente:

#include "CountArray.h"

4. Agregar la siguiente línea cerca de la cima del archivo, después de la línea CEventthreadEnd que se coloco en un paso previo:

Page 20: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 20/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

CCountArray countArray;  // declara un objeto CCountArray 

5. Elimina las lineas CEvent threadStart y CEvent threadEnd del archivo.6. Elimina las líneas del mapa de mensajes:

ON_MESSAGE(WM_THREADENDED, OnThreadended),ON_COMMAND(ID_DetieneHilo, OnDetieneHilo), yON_WM_CREATE()

7. Reemplaza la function ThreadProc() con las funciones de hilosmostradas abajo.

UINT WriteThreadProc(LPVOID param){

for(int x=0; x<10; ++x)

{ countArray.SetArray(x);::Sleep(1000);

}return 0;

}

UINT ReadThreadProc(LPVOID param){

int array[10];for (int x=0; x<20; ++x){

countArray.GetArray(array);char str[50];str[0] = 0;for (int i=0; i<10; ++i){

int len = strlen(str);wsprintf(&str[len], "%d ", array[i]);

}::MessageBox((HWND)param, str, "Read Thread",

MB_OK);}return 0;

}

8. Reemplace todo el código de la función OnIniciarHilo() con el siguiente código:

HWND hWnd = GetSafeHwnd();AfxBeginThread(WriteThreadProc, hWnd);AfxBeginThread(ReadThreadProc, hWnd);

9. Elimina las funciones OnDetieneHilo() y OnCreate() del archivo.10. Cambia al archivo ThreadView.h y elimina del listado la constante:

WM_THREADENDED = WM_USER + 10011. También, en ThreadView.h elimina las líneas:

Page 21: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 21/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

afx_msg LONG OnThreadended(WPARAM wParam, LPARAM lParam),afx_msg void OnDetieneHilo(), yafx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct)

del mapa de mensajes.

12. Usando el editor de recursos, elimina el comando Detener hilo del menú.

13. Ahora salva construye(Built) y gestiona(Execute) la nueva versión de la aplicaciónThread. Al hacerlo, aparece la ventana principal. Seleccione el comando Iniciarhilo para conseguir saltar cosas. La primera cosa que se ve es un cuadro demensaje (véase imagen abajo) mostrando los valores actuales en el vectorprotegido. Cada vez que deseches el cuadro de mensaje, reaparece con el vector,y nuevos contenidos. El cuadro de mensaje reaparecerá 20 veces.

Los valores listados en el cuadro de mensaje dependerán de cuán a menudo seacepte el cuadro de mensaje. El primer hilo está escribiendo nuevos valores en el

vector una vez cada segundo, incluso como está visualizando el contenido del vector,en el segundo hilo.

Lo importante es que en ningún momento el segundo hilo interrumpe cuando el primerhilo esta cambiar los valores del vector. Se puede decir que esto es verdad porque elarreglo siempre contiene 10 valores idénticos. Si el primer hilo fuera interrumpidocuando modifica el vector, los 10 valores en el arreglo no serian idénticos. Como semuestra en la figura.

Page 22: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 22/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

Si examinas el código fuente cuidadosamente, verá que el primer hilo, llamadoWriteThreadProc(), llama a la función miembro SetArray() de la clase arreglo, 10veces en un ciclo for. Cada vez a través del ciclo, SetArray() da al hilo el objetocríticasección, cambia el contenido del vector al contenido del numero pasado, yentonces toma el objeto sección-critica fuera otra vez. Nota la llamada a la función al

Sleep(), que suspende el hilo el numero de milisegundos dado el único argumento dela función.

Sin sincronización de hilo, puedes ver algo como esto en el cuadro de mensaje. Elsegundo hilos, llamado ReadThreadProc(), también está tratando de acceder almismo objeto crítica-sección a construir una pantalla cadena de los valores quefiguran en el arreglo. Sin embargo, si WriteThreadProc() está tratando de llenar lamatriz con nuevos valores, ReadThreadProc() tiene que esperar. Lo contrario tambiénes cierto; es decir, WriteThreadProc() no pueden acceder a los datos protegidos hastaque pueda recuperar la propiedad de la sección crítica de ReadThreadProc().

Si realmente quieres demostrar que el objeto sección-crítica está trabajando, eliminala línea criticalSection.Unlock() del final de la función miembro SetArray() de la claseCCountArray. Entonces compilar y ejecutar el programa. Esta vez cuando inicia elhilo, ningún mensaje aparece en el cuadro. ¿Por qué? Porque WriteThreadProc()toma el objeto crítica-sección y nunca la deja ir, lo que obliga al sistema a suspenderReadThreadProc() por siempre (o al menos hasta que salgas del programa).

Page 23: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 23/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

Usando Mutexes

Mutexes son un poco semejantes a secciones críticas aunque un poco máscomplicados porque permiten compartir los recursos en forma segura, no sólo entrehilos de la misma solicitud sino también entre hilos de diferentes aplicaciones.Aunque sincronizar hilos de distintas aplicaciones está fuera del alcance de este

curso, podemos obtener un poco de experiencia con mutexes utilizandolos en lugarde secciones críticas.El listado C abajo el es archivo de encabezado de la clase CCountArray2. Exceptopara el nuevo nombre de clase y el objeto mutex, este archivo cabecera es idéntico aloriginal CountArray.h. El listado D es el archivo de implementación modificado. Comopodemos observar, las funciones miembro se ven un poco diferentes cuando seutilizan mutexes en lugar de secciones críticas, a pesar de que ambos objetosproporcionan esencialmente el mismo tipo de servicios.

 ///// Listado C

#include "afxmt.h"class CCountArray2{private:

int array[10];CMutex mutex;

public:CCountArray2() {};~CCountArray2() {};void SetArray(int value);void GetArray(int dstArray[10]);

};

 /// Listado D#include "stdafx.h"#include "CountArray2.h"void CCountArray2::SetArray(int value){

CSingleLock singleLock(&mutex);singleLock.Lock();for(int x=0; x<10; ++x)

array[x] = value;}

void CCountArray2::GetArray(int dstArray[10]){

CSingleLock singleLock(&mutex);singleLock.Lock();for (int x=0; x<10; ++x)

dstArray[x] = array[x];}

Para acceder a un objeto mutex, se debe crear un objeto CSingleLock o

Page 24: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 24/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

CMultiLock, que realiza el control de acceso. La clase CCountArray2 utilizaobjetos CSingleLock porque esta clase está tratando con un solo mutex.Cuando el código está por manipular recursos protegidos (en este caso, elarreglo), se crea un objeto CSingleLock, se ve así:

CSingleLock singleLock(&mutex);

El argumento del constructor, el es un puntero al objeto hilo-sincrónico quese desea controlar. Entonces, para acceder a la mutex, se debe llamar a lafunción miembro Lock() del objeto CSingleLock:

singleLock.Loc();

Si el mutex está sin dueño, el hilo llamado se transforma en el propietario.Si otro hilo ya posee el mutex, el sistema suspende la llamada al hilo hasta

el que el mutex se libera, momento en que el hilo en tiempo de espera esdespertado y toma el control de la mutex.Para liberar el mutex, se llama a la función miembro Unlock() del objetoCSingleLock. Sin embargo, si se crea un objeto CSingleLock en la pila(en lugar de en el montón, utilizando el nuevo operador) como se muestraen la enumeración 27.10, usted no tiene que llamar a Unlock() en todos loscasos.Cuando la función sale, el objeto queda fuera de alcance, lo que provocaque se ejecute su destructor. El destructor automáticamente desbloquea elobjeto para usted.

Ejercicio (usa la versión Thread ubicada en la carpeta sincronia2 en lasubcarpeta inicio). Para ello:

1. Para probar la nueva clase CCountArray2 en la aplicación Thread,agrega los nuevos archivos CountArray2.h y CountArray2.cpp alproyecto Thread y luego borrar los archivos originales CountArray.h yCountArray.cpp archivos.

2. En ThreadView.cpp, cambiar todas las referencias de CCountArray aCCountArray2.

3. Compila, construye y ejecuta la aplicación. Observa sucomportamiento.

Porque todos los hilos a sincronizar se maneja en la clase CCountArray2,no se requieren más cambios para usar mutexes en lugar de seccionescríticas.

Page 25: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 25/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

Usando Semáforos

Aunque los Semáforos se usan como secciones críticas y mutexes en un programaMFC, la verdad, los semáforos sirven de una forma un poco diferente. En lugar de

permitir acceso a sólo un hilo a la vez, los semáforos permiten el acceso a múltipleshilos A LA VEZ para acceder a los recursos, pero solo hasta cierto punto. Es decir, lossemáforos permitir a un número máximo de hilos para acceder a un recursosimultáneamente.Cuando se crea el semáforo, debemos saber a cuántos hilos cuando muchos se lesdebe permitir acceso simultáneo a los recursos. Esto es, cada vez que un hilo capta elrecurso, el semáforo disminuye su contador interno. Cuando el contador alcanza 0,ningún otro hilo tienenacceso a los recursos protegidos hasta que algún otro hilo libere el recurso, lo cualincrementa el contador del semáforo.

Podemos crear un semáforo proporcionando el conteo inicial y el valor máximo del

contador, se ve así:

CSemaphore semaphore(2, 2);

Dado que en esta sección se estará utilizando un semáforo para crear una clase hilo-seguro, es más conveniente declarar un puntero CSemaphore como un dato miembrode la clase y luego crear el objeto CSemaphore dinámicamente en el constructor de laclase, esta acción se ve así:

semaphore = new CSemaphore(2, 2);

Se debe hacer esto porque se tiene que iniciar el dato miembro en el constructor másque en el momento de declararlo. Con los objetos crítica-sección y mutex, no setienen que proporcionar argumentos al constructores de la clase, este hecho nospermite crear el objeto al mismo tiempo en que se declaró.

Después de haber creado el objeto semáforo, se está listo para iniciar el escrutinio deacceso a los recursos. Para aplicar el proceso del escrutinio, se crea primero unobjeto CSingleLock (o CMultiLock, si estás tratando con objetos de sincronización demúltiples hilos), dándole un puntero al semáforo que se desea utilizar, se ve así:

CSingleLock singleLock(semaphore);

Luego, para disminuir el contador del semáforo, se llama a la función miembro Lock()del objeto CSingleLock:

singleLock.Lock();

En este punto, el objeto semáforo tiene que decrece su contador interno. Este nuevorecuento sigue en efecto hasta que el objeto semáforo sea liberado, lo cual puedehacerse explícitamente al llamar a la función miembro Unlock() del objeto. Se ve así:

Page 26: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 26/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

singleLock.Unlock();

Alternativamente, si hemos creado el objeto CSingleLock localmente en la pila,podemos dejar al objeto ir fuera de alcance,lo que no sólo borra automáticamente elobjeto sino también libera la retención del semáforo. En otras palabras, ambas

acciones: UnLock() y borrar el objeto CSingleLock, incrementan el contador delsemáforo, permitiendo a un hilo que espera acceder a los recursos protegidos.

El Listado E es el archivo cabecera para la clase llamada CSomeResource.CSomeResource es en su mayor parte solo útil para demostrar el uso de semáforos.La clase tiene un único de datos miembro, que es un puntero a un objetoCSemaphore. La clase también tiene un constructor y destructor, así como unafunción miembro denominada UseResource(), que es donde el semáforo se utilizará.

//Listado E SOMERESOURCE.H#include "afxmt.h"class CSomeResource{private:

CSemaphore* semaphore;public:

CSomeResource();~CSomeResource();void UseResource();

};

El Listado F muestra la implementación de la clase CSomeResource. En él se puedever que el objeto CSemaphore está construido dinámicamente en el constructor de la

clase, y se elimina en el destructor. La función miembro UseResource() simulaacceder a recursos, por alcanzar un recuento sobre el semáforo y luego dormirdurante cinco segundos, después de lo cual espera a que el semáforo sea liberadocuando la función de salidas y el objeto CSingleLock quedan fuera de alcance.

// Listado F SOMERESOURCE.CPP#include "stdafx.h"#include "SomeResource.h"CSomeResource::CSomeResource(){

semaphore = new CSemaphore(2, 2);}

CSomeResource::~CSomeResource(){delete semaphore;

}void CSomeResource::UseResource(){

CSingleLock singleLock(semaphore);singleLock.Lock();Sleep(5000);

}

Page 27: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 27/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

Ejercicio:Si modificamos la aplicación Thread para utilizar el objeto CSomeResource, sepuede observar el trabajo del semáforo. Para ello, podemos partir de la versión delproyecto Thread ubicada en la sub carpeta inicio de la carpeta sincronia3.

Implementa los siguientes pasos:

1. Borrar cualquier archivo CountArray que todavía estén en el proyecto. (EnFileView, haz clic en el archivo una vez para seleccionarlo; entonces presionaDel para borrar el archivo del proyecto.

2. Crear los nuevos archivos en el proyecto SomeResource.h ySomeResource.cpp.

3. Agregue el código del listado E y F a los archivos vacios.4. Abre ThreadView y reemplaza la linea #include “CountArray2.h con lo

siguiente:

#include "SomeResource.h"

5. Reemplace la línea CCountArray2 countArray con lo siguiente:

CSomeResource someResource;

6. Reemplace las funciones WriteThread() y ReadThreadProc() con las funcionesmostradas en el listado G.

//Listado G ThreadProc1(), ThreadProc2(), and ThreadProc3()UINT ThreadProc1(LPVOID param){

someResource.UseResource();

::MessageBox((HWND)param,"Thread 1 had access.", "Thread 1", MB_OK);return 0;

}UINT ThreadProc2(LPVOID param){

someResource.UseResource();::MessageBox((HWND)param,"Thread 2 had access.", "Thread 2", MB_OK);return 0;

}UINT ThreadProc3(LPVOID param){

someResource.UseResource();::MessageBox((HWND)param,"Thread 3 had access.", "Thread 3", MB_OK);return 0;

}

7. Reemplace el código en la función OnIniciarHilo () con el código enel listado H.

Page 28: Multi Tare A Con Hilos en Windows

5/9/2018 Multi Tare A Con Hilos en Windows - slidepdf.com

http://slidepdf.com/reader/full/multi-tare-a-con-hilos-en-windows 28/28

 

Tópicos Selectos de Programación 2011

Marcos Aguilar Andrade Unidad 3 Multitarea Thread

//Listado H Codigo para la function: OnIniciarHilo()HWND hWnd = GetSafeHwnd();AfxBeginThread(ThreadProc1, hWnd);AfxBeginThread(ThreadProc2, hWnd);AfxBeginThread(ThreadProc3, hWnd);

8. Ahora compilar y ejecutar la nueva versión de la aplicación Hilos.Cuando la ventana principal aparece, seleccione el comando Iniciarhilo. En unos cinco segundos, dos cuadros de mensaje aparecerá,informar a usted que hilo 1 e hilo 2 han accedido a los recursosprotegidos. Unos cinco segundos después de eso, aparecerá untercer cuadro de mensaje, diciéndole que el hilo 3 también tuvoacceso a los recursos. El hilo 3 tomó cinco segundos más tiempodebido a que los hilo 1 y 2 tomaron el control del recurso primero. Elsemáforo se estableció a permitir solo dos accesos simultáneos a losrecursos, el tercer hilo espero a que el hilo 1 y el hilo 2 liberaran elcontrol del semáforo. Observa la figura abajo.