Desarrollador Profesional de Juegos Programación III Unidad II Trabajando con bloqueo de datos.

Slides:



Advertisements
Presentaciones similares
Archivos de Texto. Introducción Los archivos son una secuencia de bits que se guarda en el disco duro. La ventaja de utilizar archivos es que los datos.
Advertisements

III - Gestión de memoria
Nuestro reto es educar al pensamiento, para que razone de acuerdo a ciertas reglas; con ello podremos ser más eficientes al momento en que ordenamos.
Curso de Microsoft® Word 2010
I.T.E.S.R.C. Romina Tamez Andrea Martínez Ma. De Lourdes Solís
Ejemplo de Programa C++
Estructuras de control
Resolución de Problemas y Algoritmos Buffer - Read & Readln
DIAGRAMAS DE FLUJO Y PSEUDOCÓDIGO
FUNCIONES EN C.
¿Qué es un PUNTERO?: Un puntero es un objeto que apunta a otro objeto. Es decir, una variable cuyo valor es la dirección de memoria de otra variable. No.
La estructura básica de los programas en java, algo a tener en cuenta y que debemos recordar siempre es el archivo debe llevar el nombre de la clase con.
Botones irregulares. Hola. Este tutorial explica el método para crear botones con formas irregulares y su utilidad en ejercicios de selección de objetos.
Funciones en lenguaje C
CI TEORIA semana 8 Subprogramas o funciones Definición de funciones.
FUNCIONES Y PROCEDIMIENTOS
MICROSOFT EXCEL TUTORIAL
Tema 6: Clases Antonio J. Sierra.
SCJP SUN CERTIFIED PROGRAMMER FOR JAVA 6. SCJP 6.0 SEMANA OCHO THREADS.
Tema 3 Entrada y Salida.
Archivos Programación.
Semana 5 Subprogramas..
SCJP SUN CERTIFIED PROGRAMMER FOR JAVA 6. SCJP 6.0 SEMANA OCHO THREADS.
Concurrencia: Exclusión Mútua y Sincronización
C++ LISTAS C++ 11/04/2017 Ing. Edgar Ruiz Lizama.
Conceptos generales: Concurrencia: Existencia simultánea de varios procesos en ejecución. IMPORTANTE: EXISTENCIA SIMULTÁNEA NO IMPLICA EJECUCIÓN SIMULTÁNEA.
Programación en Matlab
1 Planteamiento del problema ¿Tenemos los humanos la capacidad de percibir si nos miran desde atrás? O, más exactamente: ¿Es defendible que existen otras.
Constantes en PHP Programación en Internet II. Constantes en PHP Programación en Internet II Universidad de Guadalajara | Centro Universitario de la Costa.
Unidad III Administración de procesos
Desarrollador Profesional de Juegos Programación III Unidad II Una clase thread para window.
Archivos.

Estructura de Datos y Algoritmos
Administración de Proyectos de desarrollo de Software Ciclo de vida de un proyecto Enfoque moderno Temas Componentes Directivas Declaraciones globales.
Pablo Abrile1 Threads Lenguajes de Programación I.
Material de apoyo Unidad 4 Estructura de datos
 El acceso concurrente a datos compartidos puede dar pie a inconsistencia de datos  Mantener la consistencia de los datos requiere mecanismos para asegurar.
Sincronización de Procesos
Elementos básicos del lenguaje
Sincronización de Procesos
SCJP SUN CERTIFIED PROGRAMMER FOR JAVA 6. SCJP 6.0 SEMANA OCHO THREADS.
Informática Ingeniería en Electrónica y Automática Industrial
Universidad de Chile - Tupper 2007, Santiago - Fono/Fax: (56 2) cec.uchile.cl Módulo ECI - 11: Fundamentos de Redes de Computadores.
Teoría de Sistemas Operativos Sincronización Procesos Departamento de Electrónica 2º Semestre, 2003 Gabriel Astudillo Muñoz
Elementos básicos del lenguaje
Teoría de Sistemas Operativos Departamento de Electrónica 2º Semestre, 2002 Gabriel Astudillo Muñoz
CREAR CONTACTO EN OUTLOK Y CALENDARIO Jorge haz Armas.
Eficiencia en uso de recursos y memoria
Estructuras de Repetición (Hacer-Mientras)
Teoría de Sistemas Operativos Sincronización Procesos
INTRODUCCION A LA PROGRAMACION
LENGUAJE “C” Programación.
Fundamentos de Programación
Capítulo 2 “Subprogramas/Funciones - Arreglos”
Introducción al lenguaje PROCESSING para ARDUINO
Algoritmo.
Objetivos del tema. Hemos visto lo que es la estructura de un programa, los datos, que esos datos en realidad se convierten en variables de distinto.
Siempre escuchamos “las reglas" desde el punto de vista femenino. Ahora, vamos a presentar las reglas, desde el punto de vista masculino.
Desarrollador Profesional de Juegos Programación III Unidad I El manejador universal.
 Las funciones son un conjunto de instrucciones que realizan una tarea específica. En general toman unos valores de entrada, llamados parámetros y proporcionan.
También es conocido como proceso ligero. Es una entidad básica de utilización de CPU y esta formado por un contador de programa, algunos registros y una.
Desarrollador Profesional de Juegos Programación III Unidad II Introdución a threading en windows.
Desarrollador Profesional de Juegos Programación III Unidad II introducción a Mutex Secciones críticas.
Desarrollador Profesional de Juegos Programación III Unidad I Capturar Excepciones.
Desarrollador Profesional de Juegos Programación III Unidad I Excepciones Tipos.
Desarrollador Profesional de Juegos Programación III Unidad II Hilos de ejecución Threads.
PROF. RAFAEL MONTENEGRO B. UNELLEZ-APURE Introducci Ó n a los Arreglos (“arrays”) en C++
1 Clase 6: control (1ª parte) iic1102 – introducción a la programación.
JOANN GÓMEZ MAX SOLANO RAUL RUSTRIAN ECUACIONES DE SEGUNDO GRADO BUENAS SOMOS JOANN, RAUL Y MAX Y LES PRESENTAMOS EL TEMA ECUACIONES DE SEGUNDO GRADO.
Transcripción de la presentación:

Desarrollador Profesional de Juegos Programación III Unidad II Trabajando con bloqueo de datos

Threading en window- Mutex Temas Race conditions Que son y como se usan

Condición de carrera Una "condición de carrera" es una situación donde dos hilos compiten para leer y grabar valores en nuestros datos críticos. Nuestro programa anterior presenta una condición buena carrera donde, según el sleep que hemos previsto en nuestros hilos, un hilo puede leer o escribir datos más rápido que el otro hilo. Esto crea el concepto de un “race". ¿Qué hilo llega primero? El hilo que llena el buffer, o el hilo que lee del buffer. Obviamente, el hilo que ejecuta más rápido terminará la carrera antes que el otro hilo. Pero desde que termina de leer losd datos del buffer, ya no podría afectar negativamente a los datos del búfer.

Ahora, ¿cómo hacer que el código no se comporte de la manera que esperamos? Esta es la clásica condición de carrera que dará una mejor idea sobre trabajar con la exclusión mutua. En este ejemplo, vamos a crear dos hilos que realicen exactamente la misma tarea. El propósito de estos hilos es imprimir caracteres en la pantalla. Se imprimirá o un "." o un '#'. Se determinará qué carácter se va a imprimir de acuerdo con el último carácter impreso. Si el último carácter impreso fue un '.', el hilo imprime un "#". Asimismo, si el último carácter impreso fue un "#", el hilo imprimirá un "." Race conditions

Ejemplo #include using namespace std; static char lastChar = '#'; void threadProc(int *sleepVal) { cout << "sleepVal: " << *sleepVal << endl; for (int i = 0; i < 100; i++) { char currentChar; if (lastChar == '#') currentChar = '.'; else currentChar = '#'; Sleep(*sleepVal); lastChar = currentChar; cout << currentChar; } Race conditions

void main() { int sleepVal1 = 50; int sleepVal2 = 40; HANDLE threadHandle1; threadHandle1 = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE) threadProc, &sleepVal1, 0, NULL); HANDLE threadHandle2; threadHandle2 = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE) threadProc, &sleepVal2, 0, NULL); WaitForSingleObject( threadHandle1, INFINITE); WaitForSingleObject( threadHandle2, INFINITE); cout << endl << endl; system("pause"); }

/ / Este es el último carácter que se imprime. Se deberá protegerá con un mutex. static char lastChar = '#'; Esta es la función que los hilos ejecutarán. Acepta un valor de sleep como argumento para que podamos dormir a cada hilo con el valor que le pasemos y no tener que escribir el mismo código dos veces sólo para dormir los hilos en diferentes intervalos. void threadProc( int *sleepVal) { cout << "sleepVal: " << *sleepVal << endl; for (int i = 0; i < 100; i++) { // imprimimos 100 caracteres // este es el caracter que vamos a imprimir ESTA vez char currentChar; if (lastChar == '#') currentChar = '.'; else currentChar = '#'; //Dormimos este hilo, para que pueda correr a un ritmo diferente a los otros Sleep(*sleepVal); // seteamos el último carácter con el carácter que se va a imprimir lastChar = currentChar; cout << currentChar; // imprimimos el caracter }

Podemos predecir lo que podría suceder? Lo veremos al ejecutar el programa. int main() { Ya hablado sobre ello, pero necesitamos un valor de sleep para cada subproceso Este valor va a cambiar la velocidad a la que cada hilo se ejecutará. Le daremos valores sólo ligeramente diferentes por lo que correran y cerraran casi a la misma velocidad, Esto creará el efecto deseado. int sleepVal1 = 50; int sleepVal2 = 40; Ahora aquí está un truco muy útil. Vamos a pasar un argumento a nuestros hilos en la función de CreateThread. También recordemos que threadProc tiene un argumento (int * sleepVal) o puntero a un entero. El cuarto argumento en CreateThread es el puntero a threadProc. Cualquier dirección de un entero que pasemos en este argumento será el valor de puntero de sleepVal en threadProc. Pasamos la dirección de nuestros dos sleepVal en cada una de nuestras llamadas a CreateThread. HANDLE threadHandle; // creamos thread 1 con sleepVal1 threadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) threadProc, &sleepVal1, 0, NULL); HANDLE threadHandle2; // creamos el thread 2 con sleepVal2 threadHandle2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) threadProc, &sleepVal2, 0, NULL);

//esperamos a los threads a completar su tarea antes de terminar la aplicación WaitForSingleObject(threadHandle, INFINITE); WaitForSingleObject(threadHandle2, INFINITE); cout << endl << endl; // terminado presione un tecla para salir system("pause"); return 0; } Ahora, ¿qué se puede espera cuando se ejecuta este programa. Naturalmente que todo se comportan como se espera y ver 200 caracteres alternados entre '#‘‘ y '. ' Al menos esto es lo que queremos que nuestro programa haga. Si ejecutamos el programa y vemos los resultados que sucede?

No es exactamente lo que esperábamos no? Vimos un patrón similar a esto: ".#.##..##.#.##..##" Vemos un patrón de. 'S y #' s, con ocasionales, si no a menudo, dobles. Estos no se alternan en todos!! Pero, ¿por qué es eso? Bueno, esta es la condición de carrera clásico. ¿Cuál va a llegar primero? Un hilo se las arreglan para leer y escribir en la variable ultimocarac antes de la siguiente conversación tiene la oportunidad de hacer lo mismo? A veces sí, a veces no. Podemos ver diferentes grados de ello cambiando el sleep alrededor de los valores. Trate de hacer a los dos 50 y ejecuta la aplicación. ¿Se soluciona el problema? Es más que probable que no! Con nuestro ejemplo anterior, cuando el hilo que inserta los datos en el búfer corría a la misma velocidad que el hilo de la lectura de los datos del buffer, los dos lograron mantenerse casi en sincronía. Con este ejemplo, sin embargo, a menos que comiencen en el momento justo, los dos hilos nunca estará en sincronía. Es probable que siempre obtengamos un patrón alternante de "..##..##".

Vamos a examinar lo que sucede en este ejemplo más de cerca. Observaremos detenidamente a cada hilo y ver si podemos determinar por qué estamos obteniendo estos resultados. Así que digamos: El hilo 1 inicia y se pone a examinar la variable ultimocarac primero. Ve que ultimocarac es un '#' y establece el carácter a imprimir a un "." como se determinó. Imprime el "." y establece ultimocarac a "." y sigue como debería. Al mismo tiempo, el hilo 2 comienza a ejecutarse. Entra y ve que ultimocarac es un "." y decide imprimir un '#'. Establece el carácter que se va a imprimir en '#'. El hilo 1 continúa su ejecución, examina el último carácter y ve que todavía es un '.' entonces decide imprimir un '#'. El hilo 2 imprime ahora su '#' y establece ultimocarac a '#'. Pero el hilo 1 hace exactamente lo mismo, e imprime un '#' y establece ultimocarac a '.'. Como vemos, los dos hilos accedieron a la ultimocarac al mismo tiempo. Si ambos pueden observar ultimocarac al mismo tiempo, ambos pueden, erróneamente, determinar que van a imprimir el mismo carácter, y entonces tendremos dos caracteres impresos en pantalla. Después de jugar un poco con el programa, vemos que no tiene mucha importancia cuando en el proceso se imprimir el carácter, ni donde se establece el valor ultimocarac al nuevo caracter.

Por supuesto que podemos crear situaciones en las que los hilos parecen comportarse de la manera esperada, pero no se puede estar seguro de ello. Un simple cambio como correr las aplicaciones en un pc más lento o más rápido tiraría abajo toda la sincronización. Podemos experimentar con el valor de sleep, así como la asignación de la ultimocarac y la impresión. Entonces, ¿cómo resolver este pequeño problema? Ahora sabemos que la respuesta es con un mutex!!!! Necesitamos un mutex para que un hilo puede mantener el control completo de acceso a ultimocarac hasta que termine de trabajar con él. Bloqueará el mutex antes de leer ultimocarac. Luego desbloqueará el mutex después de escribir ultimocarac. De esta manera, cuando el otro hilo va a buscar ultimocarac, primero debe obtener un bloqueo en el mutex para asegurarse de que el otro hilo no tiene acceso al dato compartido.

Tareas Como tarea, se modificará el programa usando un mutex para que el acceso a ultimocarac se limita a un hilo a la vez. Después se creará un tercer hilo para realizar la misma tarea. Una vez hecho esto, estamos seguros que tenemos todas las herramientas que necesitamos para construir cualquier aplicación multihilo. Ciertamente, hay más trucos y formas más eficientes para manejar los hilos, hay que investigar y experimentar.