[Zurück] Inhaltsverzeichnis [Weiter]

Verwendung der "Simple DirectMedia Layer"-API

Threads

  • Einen einfachen Thread starten

Man startet einen Thread, indem man eine Funktion an SDL_CreateThread() übergibt. Wenn SDL_CreateThread() keinen Fehler meldet, läuft die übergebene Funktion parallel zum Rest des Programmes in einem eigenen Kontext (Stack, Register, ...), kann aber auf denselben Speicher und dieselben Dateien zugreifen.

Tip:
Das zweite Argument von SDL_CreateThread() wird als Argument an die Thread-Funktion übergeben. Damit kann man einen einzelnen Wert übergeben, einen Pointer auf Daten oder auch einen Pointer auf ein C++-Objekt.
Beispiel:
#include "SDL_thread.h"

int globalerWert = 0;

int threadFunktion(void *nichtVerwendet)
{
    int letzterWert = 0;

    while ( globalerWert != -1 ) {
        if ( globalerWert != letzterWert ) {
            printf("Variable wurde auf %d gesetzt.\n", globalerWert);
            letzterWert = globalerWert;
        }
        SDL_Delay(100);
    }
    printf("Thread beendet sich.\n");
    return(0);
}

{
    SDL_Thread *thread;
    int i;

    thread = SDL_CreateThread(threadFunktion, NULL);
    if ( thread == NULL ) {
        fprintf(stderr, "Thread konnte nicht gestartet werden: %s\n", SDL_GetError());
        return;
    }

    for ( i=0; i<5; ++i ) {
        printf("Variable wird auf %d gesetzt.\n", i);
        globalerWert = i;
        SDL_Delay(1000);
    }

    printf("Signalisiere dem Thread, sich zu beenden.\n");
    globalerWert = -1;
    SDL_WaitThread(thread, NULL);
}
  • Zugriff auf eine Ressource synchronisieren

Man verhindert den gleichzeitigen Zugriff mehrerer Threads auf eine Ressource, indem man ein Mutex-Objekt erstellt und den Zugriff auf die Ressource vorher schützt (SDL_mutexP()) und nachher freigibt (SDL_mutexV()).

Tip:
Alle Daten, auf die von mehr als einem Thread zugegriffen wird, sollten mit einem Mutex-Objekt geschützt werden.
Beispiel:
#include "SDL_thread.h"
#include "SDL_mutex.h"

int toepfchen = 0;
int weiterMachen;

int threadFunktion(void *data)
{
    SDL_mutex *lock = (SDL_mutex *)data;
    int rundenZahl;

    rundenZahl = 0;
    while ( weiterMachen ) {
        SDL_mutexP(lock);    /* Schütze das "Töpfchen" */
        ++toepfchen;
        printf("Thread %d verwendet das Töpfchen.\n", SDL_ThreadID());
        if ( toepfchen > 1 ) {
            printf("Oh! Jemand anderes verwendet das Töpfchen!\n");
        }
        --toepfchen;
        SDL_mutexV(lock);
        ++rundenZahl;
    }
    printf("Ja, Mama.\n");
    return(rundenZahl);
}

{
    const int nachkommen = 5;
    SDL_Thread *kinder[nachkommen];
    SDL_mutex  *lock;
    int i, lots;

    /* das Synchronisierungs-Objekt erstellen */
    lock = SDL_CreateMutex();

    weiterMachen = 1;
    for ( i=0; i<nachkommen; ++i ) {
        kinder[i] = SDL_CreateThread(threadFunktion, lock);
    }

    SDL_Delay(5*1000);
    SDL_mutexP(lock);
    printf("Alle fertig?\n");
    weiterMachen = 0;
    SDL_mutexV(lock);

    for ( i=0; i<nachkommen; ++i ) {
        SDL_WaitThread(kinder[i], &lots);
        printf("Thread %d hatte das Töpfchen %d mal.\n", i+1, lots);
    }
    SDL_DestroyMutex(lock);
}

[Zurück] Inhaltsverzeichnis [Weiter]