Transcript 04 Hilos en Windows - Academia Multicore
Programando con Hilos de Windows*
Intel Software College
Objetivos
Al término de este módulo, será capaz de: • Escribir programas para crear y terminar hilos • Usar objetos de sincronización para coordinar la ejecución entre hilos y accesos a memoria
Programming with Windows Threads 2
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Agenda
Explorar las funciones del API para hilos en Win32 • Crear hilos • Esperar que los hilos terminen • Sincronizar acceso compartido entre hilos Prácticas para experiencia práctica
Programming with Windows Threads 3
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Windows* tipo HANDLE
Cada objeto de windows es referenciado por variables de tipo
HANDLE
• Apuntador a objetos del kernel • Hilo, proceso, archivo, evento, mutex, semáforo, etc.
Las funciones para crear objetos devuelven un
HANDLE
Los objetos se controlan a través de su
HANDLE
• No se manipulan directamente los objetos
Programming with Windows Threads 4
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Creación de Hilos en Windows* HANDLE CreateThread( LPSECURITY_ATTRIBUTES ThreadAttributes, DWORD StackSize, LPTHREAD_START_ROUTINE StartAddress, LPVOID Parameter, DWORD CreationFlags, LPDWORD ThreadId ); // Out
Programming with Windows Threads 5
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
LPTHREAD_START_ROUTINE
CreateThread() espera un apuntador a una función global • Devuelve DWORD • Convención de llamadas de WINAPI • Un solo parámetro LPVOID (void *)
DWORD WINAPI MyThreadStart(LPVOID p);
El hilo inicia la ejecución de la función
Programming with Windows Threads 6
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Usando Hilos Explícitamente
Identifica porciones de código a paralelizar Encapsula código en una función • Si el código ya es una función, una función de un driver puede necesitar ser escrita para coordinar el trabajo de varios hilos Añadir la llamada CreateThread para asignar hilos para ejecutar la función
Programming with Windows Threads 7
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Destruyendo Hilos
Libera recursos del SO • Limpia si se terminó el trabajo con el hilo antes de que el programa termine La terminación del proceso lo hace
BOOL CloseHandle(HANDLE hObject); Programming with Windows Threads 8
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Ejemplo: Creación de Hilos
#include
¿Qué Sucede?
Programming with Windows Threads 9
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Explicación del Ejemplo
El hilo principal es un proceso Cuando el proceso termina, todos los hilos terminan Se requiere algún método para esperar que un hilo termine
Programming with Windows Threads 10
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Esperando un Hilo de Windows*
#include
No es una buena idea!
HANDLE hThread = CreateThread(NULL, 0, helloFunc, NULL, 0, NULL ); while (!threadDone); // ciclos desperdiciados!
Programming with Windows Threads 11
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Esperando un Hilo
Espera un objeto (hilo)
DWORD WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds );
El hilo creador de hilos espera (bloqueado) hasta • El tiempo expira • Regresa un código para indicarlo • El hilo sale (se le indica al manejador) • Usa
INFINITE
para esperar hasta la terminación del hilo No usa ciclos del CPU
Programming with Windows Threads 12
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Esperando Muchos Hilos
Espera hasta 64 objetos (hilos)
DWORD WaitForMultipleObjects( DWORD nCount, CONST HANDLE *lpHandles, // arreglo BOOL fWaitAll, // espera uno o todos DWORD dwMilliseconds)
Espera a todos:
fWaitAll==TRUE
Espera a cualquiera:
fWaitAll==FALSE
• El valor de retorno es el primer índice del arreglo encontrado
Programming with Windows Threads 13
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Detalles en las funciones WaitFor*
Descriptor (Handle) como parámetro Usado para diferentes tipos de objetos Los objetos del kernel tienen dos estados • Signaled • Non-signaled El comportamiento se define por el objeto referido por el manejador • Hilo: signaled indica terminado
Programming with Windows Threads 14
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Ejemplo: Varios Hilos
#include
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
¿Qué es Incorrecto?
¿Qué se muestra en myNum?
DWORD WINAPI threadFunc(LPVOID pArg) { int* p = (int*)pArg; int myNum = *p; printf( “Thread number %d\n”, myNum); } . . .
// from main(): for (int i = 0; i < numThreads; i++) { hThread[i] = CreateThread(NULL, 0, threadFunc, &i, 0, NULL); } Programming with Windows Threads 16
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
for(int i=0;i
Contenido de la dirección 0x0001004
DWORD WINAPI threadFunc(LPVOID pArg) { } int* p = (int*)pArg; int myNum = *p; printf( “Thread number %d\n”, myNum);
i
=0x0001004
pArg
=0x0001008 0x0001004
p
=0x000100C 1
mynum
=0x0001010 1
Programming with Windows Threads 17
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Línea de Tiempo Hello “Threads”
Tiempo main
T 0 T 1 T 2 T 3 T 4 T 5 T 6 i = 0 create(&i) i++ (i == 1) create(&i) i++ (i == 2) wait wait
Thread 0
-- -- launch p = pArg myNum = *p myNum = 2 print(2) exit
Thread 1
--- -- -- -- launch p = pArg myNum = *p myNum = 2
Programming with Windows Threads 18
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Condiciones de Concurso
Varios hilos acceden la misma variable de manera concurrente • Conflicto Lectura/Escritura • Conflicto Escritura/Escritura El error más común en programas concurrentes No siempre es obvio
Programming with Windows Threads 19
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
¿Cómo Evitar Condiciones de Concurso?
El alcance de las variables local en los hilos • Variables declaradas dentro de las funciones de los hilos • Se almacenan en el stack del hilo • TLS (Thread Local Storage) Controla el acceso compartido con regiones críticas • Exclusión mutua y sincronización • Lock, semáforo, evento, sección crítica, mutex …
Programming with Windows Threads 20
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Solución – Almacenamiento “Local”
DWORD WINAPI threadFunc(LPVOID pArg) { int myNum = *((int*)pArg); printf( “Thread number %d\n”, myNum); } . . .
// from main(): for (int i = 0; i < numThreads; i++) { tNum[i] = i; hThread[i] = CreateThread(NULL, 0, threadFunc, &tNum[i] , 0, NULL); } Programming with Windows Threads 21
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Windows* Mutexes
Objeto del kérnel que se referencía por un descriptor “Signaled” cuando está disponible • • Operaciones: •
CreateMutex(…) // crear nuevo WaitForSingleObject // wait y lock ReleaseMutex(…) // unlock
Disponible entre procesos
Programming with Windows Threads 22
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Sección Crítica en Windows*
Ligero, entre procesos solo mutex El más útil y más usado Nuevo tipo •
CRITICAL_SECTION cs;
Operaciones de crear y destruir •
InitializeCriticalSection(&cs)
•
DeleteCriticalSection(&cs); Programming with Windows Threads 23
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Sección Crítica en Windows*
CRITICAL_SECTION cs ;
Intenta entrar al código protegido
EnterCriticalSection(&cs)
• Se bloquea si otro hilo está en la sección crítica • Regresa cuando no hay hilos en la sección crítica Al salir de la sección crítica
LeaveCriticalSection(&cs)
• Debe ser desde el hilo que la obtiene
Programming with Windows Threads 24
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Ejemplo: Sección Crítica
#define NUMTHREADS 4 CRITICAL_SECTION g_cs; // ¿Por qué tiene que ser global?
int g_sum = 0; DWORD WINAPI threadFunc(LPVOID arg ) { int mySum = bigComputation(); EnterCriticalSection(&g_cs); g_sum += mySum; return 0; // Los hilos acceden una a la vez LeaveCriticalSection(&g_cs); } main() { HANDLE hThread[NUMTHREADS]; InitializeCriticalSection(&g_cs); for (int i = 0; i < NUMTHREADS; i++) hThread[i] = CreateThread(NULL,0,threadFunc,NULL,0,NULL); WaitForMultipleObjects(NUMTHREADS, hThread, TRUE, INFINITE); DeleteCriticalSection(&g_cs); } Programming with Windows Threads 25
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Ejemplo de Integración Numérica
4.0
0 1 f(x) = 4.0
4.0
(1+x 2 ) dx =
double step, pi; void main() { int i; double x, sum = 0.0; 2.0
0.0
X
1.0
step = 1.0/(double) num_steps; for (i=0; i< num_steps; i++){ x = (i+0.5)*step; sum = sum + 4.0/(1.0 + x*x); } pi = step * sum; printf(“Pi = %f\n”,pi); } Programming with Windows Threads 26
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Eventos de Windows*
Usados para enviarle a otros hilos señales de que ha ocurrido un evento • Ejemplo: los datos están disponibles, el mensaje está listo Los hilos esperan señales con la función
WaitFor
* Dos tipos de eventos • Auto-reset • Manual-reset
Programming with Windows Threads 27
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Tipos de Eventos
Auto-reset Manual-reset
El sistema automáticamente resetea el evento al estado non-signaled después de que un hilo es liberado El evento permanece en estado signaled y requiere que una función ResetEvent establezca el estado del evento a non signaled .
Precaución: Sea cuidadoso cuando se usa WaitForMultipleObjects para esperar TODOS los eventos Programming with Windows Threads 28
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Creación de Eventos en Windows*
HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, // TRUE => manual reset BOOL bInitialState, // TRUE => begin signaled LPCSTR lpName); // text name for object
Establecer
bManualReset
a TRUE para un evento “ manual-reset event ”; FALSE para un evento “ auto-reset ” Establecer
bInitialState
a TRUE para que un evento inicie en estado “ signaled ”; FALSE para iniciar “ unsignaled ”
Programming with Windows Threads 29
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Establecer y Reiniciar Eventos
Establecer un evento a un estado signaled
BOOL SetEvent( HANDLE event );
Reiniciar un evento manualmente
BOOL ResetEvent( HANDLE event );
Pulsar evento
BOOL PulseEvent( HANDLE event ); Programming with Windows Threads 30
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Ejemplo: Un Hilo Buscador
Un hilo creado busca un elemento • Manda una señal si el elemento se encuentra El hilo principal (Main Thread) espera la señal y terminación del hilo • Muestra un mensaje si el elemento se encuentra • Muestra mensaje hasta la terminación del hilo Ilustra • Usando el tipo HANDLE genérico • No esperar que cada objeto haga un signal
Programming with Windows Threads 31
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Eejemplo: Eventos
HANDLE hObj[2]; // 0 es evento, 1 es hilo DWORD WINAPI threadFunc(LPVOID arg) { BOOL bFound = bigFind() ; if (bFound) { SetEvent(hObj[0]); // señal, el dato fue encontrado bigFound() ; } } moreBigStuff() ; return 0; Programming with Windows Threads 32
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Ejempo: Función Principal
. . .
hObj[0] = CreateEvent(NULL, FALSE, FALSE, NULL); hObj[1] = CreateThread(NULL,0,threadFunc,NULL,0,NULL); /* Hacer otra cosa mientras el hilo realiza la búsqueda */ DWORD waitRet = WaitForMultipleObjects(2, hObj, FALSE , INFINITE); switch(waitRet) { case WAIT_OBJECT_0: // señal del evento printf("found it!\n"); WaitForSingleObject(hObj[1], INFINITE) ; case WAIT_OBJECT_0+1: // // señal del hilo printf("thread done\n"); break ; default: printf("wait error: ret %u\n", waitRet); break ; } . . .
Programming with Windows Threads 33
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Ejempo: Función Principal
. . .
hObj[0] = CreateEvent(NULL, FALSE, FALSE, NULL); hObj[1] = CreateThread(NULL,0,threadFunc,NULL,0,NULL); /* Do some other work while thread executes search */ DWORD waitRet = WaitForMultipleObjects(2, hObj, FALSE , INFINITE);
switch(waitRet) { case WAIT_OBJECT_0: // señal del evento printf(“encontrado!\n"); WaitForSingleObject(hObj[1], INFINITE) ; // fall thru case WAIT_OBJECT_0+1: // señal del hilo printf(“hilo terminado\n"); break ; default: printf("wait error: ret %u\n", waitRet); break ; }
. . .
Programming with Windows Threads 34
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Semáforos de Windows*
Objetos de sincronización que contienen un contador • Representa el número de recursos disponibles • Formalizados por Edsger Dijkstra (1968) Dos operaciones en los semáforos • Wait [P(s)]: El hilo espera hasta que s > 0, entonces s = s-1 • Post [V(s)]: s = s + 1 El semáforo está en estado signaled si el contador > 0
Programming with Windows Threads 35
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Win32* Creación de Semáforos
HANDLE CreateSemaphore( LPSECURITY_ATTRIBUTES lpEventAttributes, LONG lSemInitial, // Initial count value LONG lSemMax, // Maximum value for count LPCSTR lpSemName); // text name for object
Valor de
lSemMax
debe ser 1 o mayor Valor de
lSemInitial
debe ser • Mayor o igual a cero, • Menor o igual que
lSemMax
, y • No puede estar fuera del rango
Programming with Windows Threads 36
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Operaciones Wait y Post
Usa
WaitForSingleObject para esperar en un semáforo
• Si el contador es == 0, el hilo espera • Decrementa el contador en 1 cuando el contador > 0 Incrementa el semáforo (Operación Post)
BOOL ReleaseSemaphore( HANDLE hSemaphore, LONG cReleaseCount, LPLONG lpPreviousCount );
• Incrementa el contador del semáforo según el valor de
cReleaseCount
• Devuelve el valor previo del contador a través de
lpPreviousCount Programming with Windows Threads 37
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Aplicaciones de los Semáforos
Controlar el acceso a estructuras de datos de tamaño limitado • Colas, stacks, deques • Usa un contador para enumerar elementos disponibles Controla el acceso a un número finito de recursos • Descriptores de archivos, unidades de cinta, … Regula la cantidad de hilos activos dentro de una región Un semáforo binario [0,1] puede funcionar como un mutex
Programming with Windows Threads 38
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Cuidados con el uso de Semáforos
No hay propietario del semáforo Cualquier hilo puede liberar un semáforo, no solo el ultimo hilo que realizó el wait • Usar una buena práctica de programación para evitar esto No existe el concepto de semáforo abandonado • Si el hilo termina antes de realizar la operación post, se pierde el incremento del semáforo • Deadlock
Programming with Windows Threads 39
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Ejemplo: Semáforo como Mutex
El hilo principal abre el archivo de entrada, espera la terminación del hilo Los hilos • Leen la línea del archivo de entrada • Cuentan todas las palabras de cinco letras en una línea
Programming with Windows Threads 40
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Ejemplo: Principal
HANDLE hSem1, hSem2; FILE *fd; int fiveLetterCount = 0; main() { HANDLE hThread[NUMTHREADS]; hSem1 = CreateSemaphore(NULL, 1, 1, NULL); // Binary semaphore hSem2 = CreateSemaphore(NULL, 1, 1, NULL); // Binary semaphore fd = fopen(“InFile”, “r”); // Open file for read for (int i = 0; i < NUMTHREADS; i++) hThread[i] = CreateThread(NULL,0,CountFives,NULL,0,NULL); WaitForMultipleObjects(NUMTHREADS, hThread, TRUE, INFINITE); fclose(fd); } printf(“Number of five letter words is %d\n”, fiveLetterCount); Programming with Windows Threads 41
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Ejemplo: Semáforos
DWORD WINAPI CountFives(LPVOID arg) { BOOL bDone = FALSE ; char inLine[132]; int lCount = 0; } while (!bDone) { WaitForSingleObject( ReleaseSemaphore( hSem1 hSem1 , INFINITE); // accede la entrada bDone = (GetNextLine(fd, inLine) == EOF); , 1, NULL); if (!bDone) if (lCount = GetFiveLetterWordCount(inLine)) { WaitForSingleObject( ReleaseSemaphore( hSem2 hsem2 , INFINITE);//actualiza var fiveLetterCount += lCount; , 1, NULL); } } Programming with Windows Threads 42
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Programando con Hilos de Windows Que se ha Cubierto
Crear hilos para ejecutar trabajo encapsulado dentro de funciones Lo normal de esperar hilos para terminar Coordinar acceso compartido entre hilos para evitar condiciones de concurso • Almacenamiento local para evitar concursos • Objetos de sincronización para organizar el uso
Programming with Windows Threads 43
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.
Programming with Windows Threads 44
Copyright © 2006, Intel Corporation. All rights reserved. Intel and the Intel logo are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States or other countries. *Other brands and names are the property of their respective owners.