| Games and SDL SDL Installation SDL for Embedded SDL API SDL Events | SDL Graphics SDL Threads Thread Example SDL Animation SDL Sound | Raw Video Player Video Formats Video Compression | Game Trees About The Author |
| 1 | 2 | 3 |
Of course, you use threads only when you have to. You are not replacing simple nonthreaded programs with fancy, complex, threaded ones. Threads are just one more way you can use to make your programming tasks easier.
The main benefits of using threads in programming include:
A thread is also referred to as a a light weight process ( LWP ). A process is a program in execution. It is a unit of work in a modern time-sharing system. You can create several processes from the same program. A process not only includes the program code, which is sometimes referred to as the text section, but also the current activities and consumed resources including the program counter, processor registers, the process stack ( which contains temporary data such as function parameters, return address, and local variable ), and the data section, which contains global variables. A process may also have a heap, which is the memory dynamically allocated to it during run time.
A thread is a basic unit of CPU utilization, comprising a thread ID, a program counter, a register set, and a stack. It shares with its other threads of the same process its code section, data section, and other operating-system resources, such as open files, signals, and global variables. The various states of a thread can be represented by the figure shown below.

IEEE defines a POSIX standard API, referred to as Pthreads ( IEEE 1003.1c ), for thread creation and synchronization. Many contemporary systems implement the Pthreads including Linux, Solaris, and Mac OX X. To use Pthreads in your program, you must include pthread.h and link with -l pthread. The following code shows how to use Pthreads.
/*
pthreads.cpp
A very simple example demonstrating the usage of pthreads.
Compile: g++ -o pthreads_demo pthreads_demo.cpp -lpthread
Execute: ./pthreads_demo
*/
#include <pthread.h>
#include <stdio.h>
using namespace std;
//The thread
void *runner ( void *data )
{
char *tname = ( char * )data;
printf("I am %s\n", tname );
pthread_exit ( 0 );
}
int main ()
{
pthread_t id1, id2; //thread identifiers
pthread_attr_t attr1, attr2; //set of thread attributes
char *tnames[2] = { "Thread 1", "Thread 2" }; //names of threads
//get the default attributes
pthread_attr_init ( &attr1 );
pthread_attr_init ( &attr2 );
//create the threads
pthread_create ( &id1, &attr1, runner, tnames[0] );
pthread_create ( &id2, &attr2, runner, tnames[1] );
//wait for the threads to exit
pthread_join ( id1, NULL );
pthread_join ( id2, NULL );
return 0;
}
|
In the above example, we use pthread_tid to declare the identifiers for the threads we are going to create. Each thread has a set of attributes containing information about the thread like stack size and scheduling information. We use pthread_attr_t to declare the attributes of the threads and set the attributes in the function call by pthread_attr_init(). As we did not explicitly set any attributes, the default attributes will be used. The function pthread_create() is used to create a separate thread. In addition to passing the thread idenfifier and the attributes to the thread, we also pass the name of the function, runner, where the new thread will begin execution. The last argument passed to pthread_create() in the example is a string parameter containing the name of the thread. At this point, the program has three threads: the initial parent thread in main() and two child threads in runner(). After creating the child threads, the main() thread will wait for the runner() threads to complete by calling pthread_join() function.
Pthreads specification has a rich set of functions, allowing users to develop very sophisticated mulitthreaded programs. In the applications discussed here, we do not need to use many of the Pthread functions. So instead we will use SDL threads, which are much simpler and only consist of a few functions. Moreover, SDL is platform independent. Besides POSIX threads, different crucial thread programming schemes exist in the market. MS Windows has its own threading interface which is very different from POSIX threads. Though Sun's Solaris supports Pthreads, it also has its own thread API. Other UNIX systems may also have their own thread APIs. SDL solves this inconsistency with its own set of portable threading functions.
The mechanisms of using SDL Threads are basically the same as that of Pthreads. The thread functions are similar except that the names different. You start new threads with SDL_CreateThread() function, which returns a thread handle of type SDL_Thread for subsequent thread operations. The above Pthreads example can be rewritten using SDL threads as follows.
/*
sdlthreads_demo.cpp
A very simple example demonstrating the usage of sdl threads.
Compile: g++ -o sdlthread_demo sdlthread_demo.cpp -lSDL -lpthread
Execute: ./sdlthread_demo
*/
#include <SDL/SDL.h>
#include <SDL/SDL_thread.h>
#include <stdio.h>
using namespace std;
//The thread
int runner ( void *data )
{
char *tname = ( char * )data;
printf("I am %s\n", tname );
return 0;
}
int main ()
{
SDL_Thread *id1, *id2; //thread identifiers
char *tnames[2] = { "Thread 1", "Thread 2" }; //names of threads
//create the threads
id1 = SDL_CreateThread ( runner, tnames[0] );
id2 = SDL_CreateThread ( runner, tnames[1] );
//wait for the threads to exit
SDL_WaitThread ( id1, NULL );
SDL_WaitThread ( id2, NULL );
return 0;
}
|
The code is a similar to and a little simpler than the Pthreads code above. The SDL_WaitThread() function works in the same way as the Pthreads pthread_join(), which waits a thread to complete. We need to do a -lpthread link in compilation because some of the SDL thread implementations are based on the Pthreads libraries.
The following table lists all the SDL Thread functions.
|
As mentioned above, the SDL's threading API is a simplified set of threading functions. Its implementation is somewhat incomplete. For example, SDL does not allow a program to change a thread's scheduling priority or other low-level attributes. Actually, these features are highly system-dependent and supporting them would be difficult to make SDL platform independent. For most game applications, the SDL's threading API is sufficient.
The following are details of some of the basic threading functions of SDL.
| Synopsis |
#include "SDL.h"
#include "SDL_thread.h" SDL_Thread *SDL_CreateThread(int (*fn)(void *), void *data); |
|
|---|---|---|
| Description | Creates a new thread of execution that shares all of its parent's global memory, signal handlers, file descriptors, etc, and runs the function fn(), which utilizes the void pointer data passing to it. The thread quits when fn() returns. | |
| Returns | A pointer to the thread of type SDL_Thread. |
| Synopsis |
#include "SDL.h"
#include "SDL_thread.h" void SDL_KillThread(SDL_Thread *thread); |
|
|---|---|---|
| Description | Gracelessly terminates the thread associated with the thread. You should avoid using it to terminate a thread. If possible, use some other form of IPC to signal the thread to quit. | |
| Returns |
None |
| Synopsis |
#include "SDL.h"
#include "SDL_thread.h" void SDL_WaitThread(SDL_Thread *thread, int *status); |
|
|---|---|---|
| Description | Waits for a thread to finish (timeouts are not supported). | |
| Returns | The return code for the thread function is placed in the area pointed to by
status, if status is not NULL |