700 likes | 829 Views
Aplicaciones Multi-Threads-I. Ernesto Cuadros -V argas ecuadros@spc.org.pe Sociedad Peruana de Computación Perú. Organización de la presentación. Conceptos Básicos; Operaciones con hebras; Tipos de hebras; Comunicación entre hebras; Fibras; Otros puntos importantes; DEMOS;
E N D
Aplicaciones Multi-Threads-I ErnestoCuadros-Vargas ecuadros@spc.org.pe Sociedad Peruana de Computación Perú
Organización de la presentación • Conceptos Básicos; • Operaciones con hebras; • Tipos de hebras; • Comunicación entre hebras; • Fibras; • Otros puntos importantes; • DEMOS; • Sugerencias y conclusiones. Aplicaciones Multi-Hebras
Conceptos básicos • programa • programa = algoritmos + ED; • proceso • abstracción de un programa en ejecución; • hebras o threads • secuencia de ejecución de un proceso; Aplicaciones Multi-Hebras
Programa-Proceso-Hebra Memoria Aplicaciones Multi-Hebras 011011111010 cargador
Programación Multi-Threads • crear programas capaces de ejecutar más de una tarea en paralelo; • las hebras pueden estar en el mismo proceso; • estamos preparados para aprovechar mas de un procesador. Aplicaciones Multi-Hebras
Origen de las hebras Proceso 1 Aplicaciones Multi-Hebras Tiempo
Origen de las hebras (cont) Aplicaciones Multi-Hebras P1 P2 Tiempo
Algunos ejemplos • manejadores de Bases de Datos; • servidores de Web; • servidores de FTP; • grabación en segundo plano (ej. Word); • compilación sin parar la edición, etc; • nuestra vida diaria (trabajo en grupo, tareas en paralelo). Aplicaciones Multi-Hebras
Evolución • sistemas monotareas vs.sistemas multitasking • programas ST vsprogramas MT Aplicaciones Multi-Hebras
Ventajas • mayor aprovechamiento de la capacidad ociosa del procesador; • podemos aprovechar mas de un procesador; • mayor paralelismo; • menor tiempo de respuesta que en forma secuencial, etc. Aplicaciones Multi-Hebras
Desventajas • mayor complejidad; • mayor cantidad de recursos necesarios (memoria, etc); • política de planificación de procesos. Aplicaciones Multi-Hebras
Cuándo usar MT ? • cuando mi programa presenta bloques independientes; • cuando tengo una pérdida de tiempo considerable por operaciones de I/O; • NÚMERO DE PROCESADORES. Aplicaciones Multi-Hebras
Transicion de ST a MT • las hebras de ejecutan independientes unas de las otras Problemas ! • sincronización • en el mismo proceso (sibling Threads); • en procesos diferentes. Aplicaciones Multi-Hebras
Planificador de procesos (Scheduler) Aplicaciones Multi-Hebras Corriendo (Running) 3 1 2 Bloqueado (Blocked) Listos (Ready) 4
Scheduler para 2 procesadores P3 P8 Aplicaciones Multi-Hebras Corriendo (Running) Bloqueado (Blocked) Listos (Ready) P2 P1 P5 P7 P6 P4
Proceso vs Hebra • una pila (Stack); • entrada en el Scheduler; • registros de la CPU; • program counter, etc. • archivos abiertos; • variables globales; • memoria asignada dinamicamente, etc. Aplicaciones Multi-Hebras
Necesidad de Sincronización Ejemplos utilizando en la plataforma Win32 Aplicaciones Multi-Hebras
Problemas relacionados a la programación MT • Atomicidad; • Exclusión mutua: • pedir un recurso, • liberar el recurso • Race Conditions: • Un bug que depende del orden en el que se ejecuten dos o más tareas independientes Aplicaciones Multi-Hebras
Atomicidad y exclusión mutua Aplicaciones Multi-Hebras
Atomicidad (cont) Aplicaciones Multi-Hebras • HANDLE hIOMutex= ::CreateMutex (NULL, FALSE, 0); • // Pedir acceso al recurso • ::WaitForSingleObject( hIOMutex, INFINITE ); • // Realizar nuestra operación crítica • ::fseek( fp, desired_position, 0L ); • ::fwrite( data, sizeof( data ), 1, fp ); • // Liberar el acceso al recurso • ::ReleaseMutex(hIOMutex);
Race Conditions Aplicaciones Multi-Hebras
Problemas relacionados a programación MT (cont) • Deadlock; • Diseño de clases seguras para ambientes MT; • Starvation (morir de hambre) • Threads de prioridades altas siempre ganaran el procesador. Aplicaciones Multi-Hebras
Deadlock (bloqueo mutuo) Aplicaciones Multi-Hebras
Clases seguras para ambientes MT void MyClass::PrintPersonalInfo(){ m_report = Datos_Personales; Imprimir();} void MyClass::PrintHistorico(){ m_report = Historico; Imprimir();} Aplicaciones Multi-Hebras Thread1 Thread2 void MyClass::Imprimir(){ switch(m_report) { case Datos_Personales: …… break; case Datos_Personales: …… break; }}
Mecanismos de Sincronización • por la cantidad de estados: • binarios, • de múltiples estados. • por su alcance: • dentro del mismo proceso, • entre procesos. Aplicaciones Multi-Hebras
Por la cantidad de estados • binarios • Events (CEvent), • CriticalSection (CCriticalSection), • Mutex (CMutex). • de múltiples estados: • Semáforos (CSemaphore) Aplicaciones Multi-Hebras
Por su alcance • dentro del mismo proceso: • CriticalSection • entre procesos: • Event, Mutex, Semáforos, • también sirven en el mismo proceso. Aplicaciones Multi-Hebras
Entre procesos Aplicaciones Multi-Hebras Semáforo “Impresion” Handle(35) Semáforo “Impresion” Handle(7) Proceso 1 Proceso 2 Win32 Semaphore “Impresion” Kernel Object Usage Counter=2More information ….
Tipos de hebras • worker threads o hebras trabajadoras; • hebras con interface de usuario. Aplicaciones Multi-Hebras
Worker Thread • para tareas en background o en segundo plano; • cuando no necesitamos enviar o recibir mensajes a través de ventanas; • no es necesario interactuar con la hebra. Aplicaciones Multi-Hebras
Pasos para crear una Worker Thread • programar una función que será al “main” de la hebra, • crear la hebra propiamente dicha con alguna de las funciones API (CreateThread, _beginthread) Aplicaciones Multi-Hebras
Paso 1: Programar una función que será el “main” de la hebra DWORDWINAPI MyThreadMain(LPVOID lpParameter) { CStudent *pMyObj = (CStudent *)lpParameter; pMyObj->MyMethod1(); pMyObj->MyMethod2(); . . . return 0L; } Aplicaciones Multi-Hebras
Paso 2: Creación de una Thread con CreateThread HANDLECreateThread( // puntero a los atributos de securidad LPSECURITY_ATTRIBUTES lpThreadAttributes, // Tamaño inicial del Stack para esta hebra DWORD dwStackSize, // puntero a la función de la hebra LPTHREAD_START_ROUTINE lpStartAddress, // argumento para la nueva hebra LPVOID lpParameter, // atributos de creación DWORD dwCreationFlags, // puntero para recibir el ID de la hebra LPDWORD lpThreadId ); Aplicaciones Multi-Hebras
Paso 2: Creación de una Thread con CreateThread (cont) CStudent *pMyObj = new CStudent; DWORD ThreadID; HANDLE myhandle = CreateThread( NULL, 4096, &MyThreadMain, (LPVOID)pMyObj, 0, // CREATE_SUSPENDED &ThreadId ); Aplicaciones Multi-Hebras
Hebras usando C Run-Time Library void __cdecl MyThreadMain2(void *lpParameter) { CStudent *pMyObj = (CStudent *)lpParameter; pMyObj->MyMethod1(); pMyObj->MyMethod2(); . . . return 0L; } Aplicaciones Multi-Hebras
Paso 2: Creación de una Thread con _beginthread (cont) unsigned long _beginthread( // Puntero a la funcion que controlará la hebravoid( __cdecl *start_address )( void * ),// Tamaño del stack unsigned stack_size,// Lista de argumentos void *arglist ); HANDLE handle = (HANDLE)_beginthread( & MyThreadMain2, 4096, NULL); Aplicaciones Multi-Hebras
Operaciones básicas con una hebra • ::WaitForSingleObject(hThread, 5); • ::WaitForSingleObject(hThread, INFINITE); • ::SuspendThread(hThread); • ::ResumeThread(hThread); Aplicaciones Multi-Hebras
Prioridades de una Thread (SetThreadPriority) ::SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL); • THREAD_PRIORITY_ABOVE_NORMAL; • THREAD_PRIORITY_BELOW_NORMAL; • THREAD_PRIORITY_HIGHEST; • THREAD_PRIORITY_IDLE; • THREAD_PRIORITY_LOWEST; • THREAD_PRIORITY_NORMAL; • THREAD_PRIORITY_TIME_CRITICAL. Aplicaciones Multi-Hebras
Prioridades para todo el proceso ::SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); • HIGH_PRIORITY_CLASS; • IDLE_PRIORITY_CLASS; • NORMAL_PRIORITY_CLASS; • REALTIME_PRIORITY_CLASS. Aplicaciones Multi-Hebras
Demo Worker Threads Break ! Aplicaciones Multi-Hebras
Aplicaciones Multi-Threads-II ErnestoCuadros-Vargas ecuadros@spc.org.pe Sociedad Peruana de Computación Piura-Perú
Hebras con interface • útiles cuando necesitamos enviar mensajes o interactuar a través de algún mecanismo visible al usuario (generalmente una ventana) • existe la clase CWinThread (MFC) Aplicaciones Multi-Hebras
Secuencia de creación • crear la clase heredada de CWinThread (inicialmente esta vacía); BOOL CMyThread::InitInstance() { returnTRUE; } • crear la hebra hija; Aplicaciones Multi-Hebras
Crear la hebra hija void CMainFrame::OnNuevaThread() { // TODO: Add your command handler code here CRuntimeClass *pRuntimeClass = RUNTIME_CLASS(CMyThread); CMyThread *pMyThread = (CMyThread *)pRuntimeClass->CreateObject(); pMyThread->CreateThread(); } Aplicaciones Multi-Hebras
Crear la hebra hija (cont) BOOL CMyThread::InitInstance() { CSingleDocTemplate* pDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CTeste2Doc), // clase del documento RUNTIME_CLASS(CMainFrame), // clase del MainFrame RUNTIME_CLASS(CTeste2View)); // clase del área de cliente // Crear un nuevo documento para esta ventana CDocument *pDoc = pDocTemplate->CreateNewDocument(); // Crear la ventana propiamente dicha m_pMainWnd = pDocTemplate->CreateNewFrame(pDoc, NULL); // Hacerla visible m_pMainWnd->ShowWindow(SW_SHOW); // Enviarle un mensage de actualizacion m_pMainWnd->UpdateWindow(); return TRUE; } Aplicaciones Multi-Hebras
Comunicación entre ventanas y/o hebras • colas de mensajes • de tamaño fijo en Win16 • dinámicas en Win32 (listas enlazadas) • SendMessage • PostMessage • PostThreadMessage • SendMessageTimeout Aplicaciones Multi-Hebras
PostMessage • PostMessage(HWND hWnd, UINT msg, WPARAM, LPARAM); • coloca el mensaje en la fila de la hebra que creó hWnd y retorna. Aplicaciones Multi-Hebras
SendMessage • SendMessage(HWND hWnd, UINT msg, WPARAM, LPARAM) • coloca el mensaje en la fila de la hebra que creó hWnd • espera hasta que el mensaje sea procesado • retorna Aplicaciones Multi-Hebras
PostThreadMessage • PostThreadMessage(DWORD ThreadID,UINT msg, WPARAM, LPARAM) • coloca el mensaje en la fila de la hebra identificada con ThreadID • retorna Aplicaciones Multi-Hebras
Importante:SendMessage (entre ventanas) • una ventana procesa sus mensajes cuando la hebra que la creo esta activa! • un mensaje siempre va a la cola de mensajes de la hebra que la creó. Aplicaciones Multi-Hebras