[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]