SDL mutex example

In the following thread programming example, there are two worker threads which print messages. The message printing is not scrambled, as would be the case were not the string printing operation an 'atomic' operation. The main thread waits for the workers to finish.

   1 #define WORK_AMOUNT 5
   2 
   3 #include <stdio.h>
   4 #include <stdlib.h>
   5 #include "SDL.h"
   6 #include "SDL_thread.h"
   7 
   8 // Global variables
   9 SDL_mutex* console_mutex;
  10 SDL_Thread* thread1;
  11 SDL_Thread* thread2;
  12 
  13 /*
  14 This string-printing routine is thread-safe. The delaying makes it possible for a human
  15 reader to see what's going on during program execution.
  16 Try commenting out the Lock/Unlock rows and see what happens.
  17 */
  18 void safePrintStr(char* str)
  19 {
  20     /*
  21     Make sure only one thread at a time gets access to the lines 
  22     between Lock/Unlock (also known as a critical region)
  23     */
  24     SDL_LockMutex(console_mutex);
  25 
  26     int i;
  27     for(i = 0; str[i]; ++i) {
  28         printf("%c", str[i]);
  29         SDL_Delay(10);
  30     }
  31 
  32     // Release the lock
  33     SDL_UnlockMutex(console_mutex);
  34 }
  35 
  36 
  37 // This is the routine that embodies a worker thread
  38 int printer(void* data)
  39 {
  40     // Start with identifying myself.
  41     char* name = (char*)data;
  42     char buf[80];
  43     sprintf(buf, "Worker '%s' started.\n", name);
  44     safePrintStr(buf);
  45 
  46     // Make sure workers work at different paces
  47     int pace;
  48     if (name[0] == 'A')
  49         pace = 1000;
  50     if (name[0] == 'B')
  51         pace = 2500;
  52 
  53     // This loop does the work
  54     int workLeft = WORK_AMOUNT;
  55     while (workLeft > 0) {
  56         // Display a message before every step of work I do.
  57         int step = 1+WORK_AMOUNT-workLeft;
  58         int percent = 100 * step / WORK_AMOUNT;
  59         sprintf(buf, "Worker '%s' is doing step %d of %d (%d%% finished).\n", name, step, WORK_AMOUNT, percent);
  60         safePrintStr(buf);
  61 
  62         // Do my work...
  63         workLeft--;
  64         SDL_Delay(pace);
  65     }
  66 
  67     // I'm done!
  68     sprintf(buf, "Worker '%s' is done.\n", name);
  69     safePrintStr(buf);
  70 
  71     return 0;
  72 }
  73 
  74 
  75 // Boot-up code
  76 void init()
  77 {
  78     SDL_Init(0);
  79     console_mutex = SDL_CreateMutex();
  80 }
  81 
  82 
  83 // Shut-down code
  84 void quit()
  85 {
  86     SDL_DestroyMutex(console_mutex);
  87     SDL_Quit();
  88 }
  89 
  90 
  91 // Program entry point
  92 int main(int argc, char* argv[])
  93 {
  94     init();
  95 
  96     // Run the two worker threads
  97     // Note: it can be necessary to add (void*) before "Alpha" and "Beta"
  98     // else this error apears: invalid conversion from 'const void*' to 'void*'
  99     thread1 = SDL_CreateThread(printer, "Alpha");
 100     thread2 = SDL_CreateThread(printer, "Beta"); 
 101 
 102     // The main thread is put to sleep until both worker threads are done.
 103     SDL_WaitThread(thread1, NULL);
 104     SDL_WaitThread(thread2, NULL);
 105 
 106     // Note: we don't have to use safePrintStr here since
 107     // we're the only thread active.
 108     printf("Main thread has done its waiting, now quit.\n");
 109     quit();
 110 
 111     return 0;
 112 }

See also

SDL_CreateThread, SDL_WaitThread, SDL_LockMutex, SDL_UnlockMutex


CategoryExample

SDL_Mutex_Example (last edited 2008-08-20 15:21:00 by NeoNeurone)