[Precedente]
Contenuti
[Successivo]
Usare la Simple DirectMedia Layer API
I Thread
- Creare un semplice thread
La creazione dei thread e' effettuata passando una
funzione a SDL_CreateThread(). Quando la funzione
ritorna, se non ci sono stati errori, la funzione
passata e' in esecuzione in modo concorrente al resto
del programma, nel suo spazio in termini di stack,
registri, ecc. Il thread cosi' creato puo' accedere
alla memoria ed ai gestori di file usati dal resto
dell'applicazione.
|
Suggerimento:
Il secondo argomento di SDL_CreateThread() viene passato come
parametro alla finzione thread. Usando questo sistema, e'
possibile avere funzioni-thread parametrizzate, passare
alle funzioni valori sullo stack, oppure semplicemente puntatori
ai dati che verranno utilizzati. |
Esempio:
#include "SDL_thread.h"
int global_data = 0;
int thread_func(void *unused)
{
int last_value = 0;
while ( global_data != -1 ) {
if ( global_data != last_value ) {
printf("Valore cambiato a %d\n", global_data);
last_value = global_data;
}
SDL_Delay(100);
}
printf("Thread in terminazione\n");
return(0);
}
{
SDL_Thread *thread;
int i;
thread = SDL_CreateThread(thread_func, NULL);
if ( thread == NULL ) {
fprintf(stderr, "Impossibile creare il thread: %s\n"
, SDL_GetError());
return;
}
for ( i=0; i<5; ++i ) {
printf("Cambio il valore a %d\n", i);
global_data = i;
SDL_Delay(1000);
}
printf("Mando il segnale di quit al therad\n");
global_data = -1;
SDL_WaitThread(thread, NULL);
}
|
- Sincronizzazione dell'accesso alle risorse
E' possibile evitare che piu' di un thread acceda
ad una risorsa creando un semaforo binario (mutex)
e delimitando la zona critica dell'accesso alla
risorsa bloccandola (con una chiamata SDL_mutexP())
e sbloccandola (con SDL_mutexV()) successivamente,
in modo che un altro thread possa accedervi.
|
Suggerimento:
Ogni dato che puo' essere modificato da piu' di un thread dovrebbe
essere protetto da un semaforo binario (mutex). |
Esempio:
#include "SDL_thread.h"
#include "SDL_mutex.h"
int potty = 0;
int gotta_go;
int thread_func(void *data)
{
SDL_mutex *lock = (SDL_mutex *)data;
int times_went;
times_went = 0;
while ( gotta_go ) {
SDL_mutexP(lock); /* Blocca la risorsa (potty) */
++potty;
printf("Il thread %d usa la risorsa\n", SDL_ThreadID());
if ( potty > 1 ) {
printf("Uh oh, qualcun'altro sta usando la risorsa!\n");
}
--potty;
SDL_mutexV(lock);
++times_went;
}
printf("Si\n");
return(times_went);
}
{
const int progeny = 5;
SDL_Thread *kids[progeny];
SDL_mutex *lock;
int i, lots;
/* Create the synchronization lock */
lock = SDL_CreateMutex();
gotta_go = 1;
for ( i=0; i<progeny; ++i ) {
kids[i] = SDL_CreateThread(thread_func, lock);
}
SDL_Delay(5*1000);
SDL_mutexP(lock);
printf("Tutti hanno finito?\n");
gotta_go = 0;
SDL_mutexV(lock);
for ( i=0; i<progeny; ++i ) {
SDL_WaitThread(kids[i], &lots);
printf("Il thread %d ha usato la risorsa %d volte\n",
i+1, lots);
}
SDL_DestroyMutex(lock);
}
|
[Precedente]
Contenuti
[Successivo]
|