[Prev] Table Of Contents [Next]

Using the Simple DirectMedia Layer API

Threads

  • Create a simple thread

Creating a thread is done by passing a function to SDL_CreateThread(). When the function returns, if successful, your function is now running concurrently with the rest of your application, in its own running context (stack, registers, etc.) and able to access memory and file handles used by the rest of the application.

Tip:
The second argument to SDL_CreateThread() is passed as a parameter to the thread function. You can use this to pass in values on the stack, or just a pointer to data for use by the thread.
Example:
#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("Data value changed to %d\n", global_data);
            last_value = global_data;
        }
        SDL_Delay(100);
    }
    printf("Thread quitting\n");
    return(0);
}

{
    SDL_Thread *thread;
    int i;

    thread = SDL_CreateThread(thread_func, NULL);
    if ( thread == NULL ) {
        fprintf(stderr, "Unable to create thread: %s\n", SDL_GetError());
        return;
    }

    for ( i=0; i<5; ++i ) {
        printf("Changing value to %d\n", i);
        global_data = i;
        SDL_Delay(1000);
    }

    printf("Signaling thread to quit\n");
    global_data = -1;
    SDL_WaitThread(thread, NULL);
}
  • Synchronizing access to a resource

You can prevent more than one thread from accessing a resource by creating a mutex and surrounding access to that resource with lock (SDL_mutexP()) and unlock (SDL_mutexV()) calls.

Tip:
Any data that can be accessed by more than one thread should be protected by a mutex.
Example:
#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);    /* Lock  the potty */
        ++potty;
        printf("Thread %d using the potty\n", SDL_ThreadID());
        if ( potty > 1 ) {
            printf("Uh oh, somebody else is using the potty!\n");
        }
        --potty;
        SDL_mutexV(lock);
        ++times_went;
    }
    printf("Yep\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("Everybody done?\n");
    gotta_go = 0;
    SDL_mutexV(lock);

    for ( i=0; i<progeny; ++i ) {
        SDL_WaitThread(kids[i], &lots);
        printf("Thread %d used the potty %d times\n", i+1, lots);
    }
    SDL_DestroyMutex(lock);
}

[Prev] Table Of Contents [Next]