Story Transcript
h Lo normal es que existan varios niveles de prioridad (en Windows CE 256). 0 es la máxima prioridad y 255 la mínima. h Cuando se crea un hilo, el sistema le asigna una prioridad por defecto ( en windows CE THREAD_PRIORITY_NORMAL=251), pero se puede cambiar. Usando la función: ceSetThreadPriority(mihilo,prioridad) • mihilo: es el manejador devuelto por CreateThread • prioridad: es la nueva prioridad del hilo (entre 0 y 255). Hay algunos valores predefinidos: THREAD_PRIORITY_TIME_CRITICAL Æ 3 puntos más de la prioridad nornal. THREAD_PRIORITY_HIGHEST Æ 2 puntos más de la prioridad nornal. THREAD_PRIORITY_ABOVE_NORMAL Æ 1 punto más de la prioridad nornal. THREAD_PRIORITY_NORMAL Æ prioridad nornal. THREAD_PRIORITY_BELOW_NORMAL Æ 1 punto menos de la prioridad nornal. THREAD_PRIORITY_LOWEST Æ 2 puntos menos de la prioridad nornal. THREAD_PRIORITY_ABOVE_IDLE Æ 3 puntos menos de la prioridad nornal. THREAD_PRIORITY_IDLE Æ 4 puntos menosde la prioridad nornal.
h Para obtener la prioridad de hilo se usa la función: prioridad = ceGetThreadPriority(mihilo,prioridad) • mihilo: es el manejador devuelto por CreateThread • prioridad: es la prioridad del hilo mihilo
25
Tema 6.2: Programación de Sistemas en Tiempo Real Informática Industrial 3º Ing. Técnico Industrial en Electrónica Industrial
h Es el trozo de código de una tarea que: – Accede a los recursos compartidos entre distintos hilos, siempre y cuando exista el riesgo de que al menos uno de esto lo modifique causando una posible corrupción de datos. – Ejecuta un código que una vez que comienza debe ser procesado lo antes posible
h En ambos casos lo que se pretende es ejecutar un trozo de código sin ser interrumpido h Las secciones críticas deben ser los más pequeñas posibles h A veces el uso de recursos también se conoce como sección o región crítica
26
Tema 6.2: Programación de Sistemas en Tiempo Real Informática Industrial 3º Ing. Técnico Industrial en Electrónica Industrial
h Típico error que se produce cuando un hilo depende del resultado de otro para completar alguna acción – Si no hay sincronización entre ambos puede ser que el hilo utilice los datos antes de ser actualizados
Tema 6.2: Programación de Sistemas en Tiempo Real Informática Industrial 3º Ing. Técnico Industrial en Electrónica Industrial
27
h Permite un cooperación entren los hilos de un sistema. h En Windows CE la función para realizar la sincronización es: WaitForSingleObject(objeto, miliseg); • objeto: es una variable HANDLE, y será el elemento por el que el hilo esperará. Puede ser – Otro hilo – un mutex – Un evento
• miliseg : tiempo máximo, en milisegundos, que el hilo estará suspendido en espera del objeto. Se puede poner INFINITE.
28
Tema 6.2: Programación de Sistemas en Tiempo Real Informática Industrial 3º Ing. Técnico Industrial en Electrónica Industrial
Sincronización: Esperar a que otro hilo acabe h Un hilo quedará suspendido hasta que otro hilo acabe. Hilo 1
#include "stdafx.h" DWORD WINAPI puntodeentrada (LPVOID nada);
Ejecuta código
Hilo 2
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow) { Espera Ejecuta Final hilo2 HANDLE hilo; código hilo = CreateThread(NULL,0,puntodeentrada,NULL,0,NULL); printf("\nHilo creado y lo espero\n"); Continúa la FIN WaitForSingleObject(hilo,INFINITE); ejecución printf(“El hilo se ha muerto\n"); Sleep(4000); return 0; } DWORD WINAPI puntodeentrada (LPVOID nada) Salida por pantalla { printf(“\tEstoy en el hilo y me duermo\n"); Hilo creado y lo espero Sleep(2000); Estoy en el hilo y me duermo printf(“\tel hilo se va a acabar\n"); El hilo se va a acabar return 0; El hilo se ha muerto } 11 12 1 2 10 9 3 8 4 7 6 5
29
Tema 6.2: Programación de Sistemas en Tiempo Real Informática Industrial 3º Ing. Técnico Industrial en Electrónica Industrial
h Es un semáforo binario, y se usa para proteger la entrada en una sección crítica. h Casi siempre es aplicable. h Gracias a su sencillez es el más usado. h Un hilo antes de entra en la sección crítica pregunta si se puede bloquear. h Cuando acaba la sección crítica desbloquea. 30
Tema 6.2: Programación de Sistemas en Tiempo Real Informática Industrial 3º Ing. Técnico Industrial en Electrónica Industrial
Sincronización: Mutex (en Windows CE) h Para crear un mutex: HANDLE MiMutex; // Un manejador para el mutex MiMutex = CreateMutex(NULL,FALSE,nombre ); • nombre: por el que se conocerá el mutex.
h Para bloquear un mutex sólo hay que esperar por él, esta función lo bloquea en el caso de que esté disponible: WaitForSingleObject(MiMutex, miliseg);
• MiMutex: manejador devuelto por CreateMutex • miliseg : tiempo máximo, en milisegundos, que el hilo estará suspendido en espera del objeto. Se puede poner INFINITE.
h Para desbloquear un mutex hay que llamar a la función: ReleaseMutex(MiMutex)
• MiMutex: manejador devuelto por CreateMutex 31
Tema 6.2: Programación de Sistemas en Tiempo Real Informática Industrial 3º Ing. Técnico Industrial en Electrónica Industrial
h Apartado C del ejercicio 3 de la práctica 4 Al principio del fichero frutaDlg.cpp, declaramos un HANDLE global para el mutex ... void escribir_bd(void); HANDLE mutexdb; ... En la función asociada al botón, creamos el mutex void CFrutaDlg::OnFruta() { ventana=this; mutexdb=CreateMutex(NULL,FALSE,_T(“bloqueado Base de datos”); ... En cada hilo de llenado de bote ... ventana->SetDlgItemInt(IDC_EDIT3,cfresas); for(f=0;fm_DB.AddString(_T("---- FRESAS")); escribir_bd(); ReleaseMutex(mutexdb); ... 32
Tema 6.2: Programación de Sistemas en Tiempo Real Informática Industrial 3º Ing. Técnico Industrial en Electrónica Industrial
h Un evento es una señal que un hilo envía al resto h Sirve para comunicar algún suceso, o simplemente que un hilo ha pasado un determinado punto del código. h Un evento puede estar:
11 12 1 2 10 9 3 8 4 7 6 5
Hilo 1
Hilo 2
Ejecuta código
Ejecuta código
Espera evento
condición SI
Continúa la ejecución
– Señalizado: el evento ha ocurrido. – No señalizado: el evento no ha ocurrido o ya ha sido leído.
Señala evento
NO
Continúa la ejecución
Tema 6.2: Programación de Sistemas en Tiempo Real Informática Industrial 3º Ing. Técnico Industrial en Electrónica Industrial
33
Sincronización: Eventos (en Windows CE) h Para crear un evento: HANDLE MiEvento; // Un manejador para el evento MiEvento = CreateEvent(NULL,FALSE,modo,nombre ); • Modo: TRUE la deseñalización es manual. FALSE la deseñalización es automática tras reactivar a todos los hilo que esperan • nombre: por el que se conocerá el evento.
h Para señalizar un evento: SetEvent(MiEvento); • MiEvento: manejador devuelto por CreateEvent.
h Para señalizar un evento enviando un dato: SetEvent(MiEvento,dato); • MiEvento: manejador devuelto por CreateEvent. • dato: dato a enviar de tipo DWORD 34
Tema 6.2: Programación de Sistemas en Tiempo Real Informática Industrial 3º Ing. Técnico Industrial en Electrónica Industrial
Sincronización: Eventos (en Windows CE) h Para deseñalizar un evento: ResetEvent(MiEvento); • MiEvento: manejador devuelto por CreateEvent.
h Para esperar a un evento: WaitForSingleObject(MiEvent, miliseg); • MiEvento: manejador devuelto por CreateEvent. • miliseg : tiempo máximo, en milisegundos, que el hilo estará suspendido en espera. Se puede poner INFINITE.
h Para señalizar un evento, reactivar todos los hilos que esperan y deseñalizar el evento: PulseEvent(MiEvent) • MiEvento: manejador devuelto por CreateEvent. Tema 6.2: Programación de Sistemas en Tiempo Real Informática Industrial 3º Ing. Técnico Industrial en Electrónica Industrial
35
h Productor-Consumidor – Si el consumidor es mas rápido que el productor o el productor no tiene datos, puede ocurrir que la FIFO se quede vacía. – Si el FIFO está vacía el consumidor debe está continuamente preguntando si hay dato en la FIFO.
Supongamos que existen las funciones InsertaDato, ExtraeDato, ProduceDato y ConsumeData. Escribir el código de dos hilos: Productor y Consumidor. Con las siguientes especificaciones. – Si no hay datos en la FIFO el consumidor se suspenderá hasta que los haya – Si el productor, tras insertar un dato, detecta que solo hay un dato en la FIFO, debe reactivar al consumidor.
Escribir el código del hilo principal.
36
Tema 6.2: Programación de Sistemas en Tiempo Real Informática Industrial 3º Ing. Técnico Industrial en Electrónica Industrial
#include "stdafx.h" typedef long dato_t; DWORD WINAPI productor (LPVOID nada); DWORD WINAPI consumidor (LPVOID nada); void ProduceDato(dato_t *dato); void ConsumeDato(dato_t dato); int num_elementos=0; void InsertaDato(dato_t dato); void ExtraeDato(dato_t *dato); HANDLE hayundato; int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR int nCmdShow){ HANDLE hiloproductor,hiloconsumidor; hayundato=CreateEvent(NULL,TRUE,FALSE,_T("UN DATO"));
lpCmdLine,
hiloproductor = CreateThread(NULL,0,productor,NULL,0,NULL); hiloconsumidor = CreateThread(NULL,0,consumidor,NULL,0,NULL); //otras cosas que hacer WaitForSingleObject(hiloproductor,INFINITE); WaitForSingleObject(hiloconsumidor,INFINITE); Sleep(4000); return 0; } 37
Tema 6.2: Programación de Sistemas en Tiempo Real Informática Industrial 3º Ing. Técnico Industrial en Electrónica Industrial
DWORD WINAPI consumidor (LPVOID nada) { dato_t dato; int ic=0; Sleep (5000); for(ic=0;ic