Related YoLinux tutorials:
°Software development tools
°Emacs and C/C++
°C++ Info, links
°MS/Visual C++ Practices
°C++ Memory corruption and leaks
°C++ String Class
°C++ STL vector, list
°Google C++ Unit Test
°Jenkins Plugins for C++
°YoLinux Tutorials Index
Free Information Technology Magazines and Document Downloads
Free Information Technology Software and Development Magazine Subscriptions and Document Downloads
|Introduction to GDK threads:
This tutorial will cover using the Gnome GDK thread library
to build a multi-threaded, parallel processing application for cross platform
GDK threads is a component of the GNOME
applications development environment which also includes multi-platform API's
for GUIs, graphics, video, window management, XML parsing, internationalization,
database access and general application development.
The GNOME thread libraries can be used without the GNOME desktop or GUI
The API's support the "C"
computer language. I usually encapsulate these calls within C++ objects
Threads allow one to spawn a new concurrent process flow.
It is most effective on multiprocessor systems where the process flow can be
scheduled by the operating system to run on another processor thus gaining
speed through parallel or distributed processing.
The GNOME thread libraries are not a feature rich as POSIX threads but
do provide the basic infrastructure.
For more information on programming threads and concepts, see the
YoLinux POSIX Threads Tutorial.
For downloading, installation and configuration of the development environment
on Ms/Windows with
MS/Visual C++ or Cygwin as well as Linux see the
YoLinux GTK+ Programming Tutorial
The basic framework of a GDK multi-threaded program requires:
- the include file: gtk/gtk.h
- functions to spawn in a separate thread.
- main program.
- a call to gtk_init (&argc, &argv);
- calls to initialize the threads infrastructure: g_thread_init() and
- spawn a thread: g_thread_create()
- protect data from corruption and contention issues with gdk_threads_mutex
- if not using processing time and you wish to "yield" to other tasks
- if a GTK+ GUI application, protect GTK+ calls using
gdk_threads_enter() and gdk_threads_leave()
- Pass conditional information to a thread using g_cond_signal()
- wait to complete thread process: g_thread_join() or terminate
(riskier due to race condition potential) using g_thread_exit().
void *print_message_function( void *ptr );
GThread *Thread1, *Thread2;
char *message1 = "Thread 1";
char *message2 = "Thread 2";
GError *err1 = NULL ;
GError *err2 = NULL ;
if( !g_thread_supported() )
gdk_threads_init(); // Called to initialize internal mutex "gdk_threads_mutex".
printf("g_thread NOT supported\n");
if( (Thread1 = g_thread_create((GThreadFunc)print_message_function, (void *)message1, TRUE, &err1)) == NULL)
printf("Thread create failed: %s!!\n", err1->message );
g_error_free ( err1 ) ;
if( (Thread2 = g_thread_create((GThreadFunc)print_message_function, (void *)message2, TRUE, &err2)) == NULL)
printf("Thread create failed: %s!!\n", err2->message );
g_error_free ( err2 ) ;
void *print_message_function( void *ptr )
message = (char *) ptr;
printf("%s \n", message);
printf("%s \n", message);
Linux Compile: gcc -o gdk-thread-only gdk-thread-only.c `pkg-config --cflags --libs gtk+-2.0 gthread-2.0`
A mutex is necessary to protect data from corruption or unexpected behavior.
See the YoLinux POSIX threads tutorial discussion on mutexes and thread synchronization.
Declare mutex outside of thread scope where it is visible to threaded function:
- C++ class member variable initialized in constructor.
- Global variable.
// Declare outside of thread scope:
static GMutex *mutex_to_protext_variable_ABC = NULL;
// Initialize Mutex
g_assert (mutex_to_protext_variable_ABC == NULL);
mutex_to_protext_variable_ABC = g_mutex_new();
// Within threaded function, protect variable with a mutex.
ABC = updateFunction();
- All of the g_mutex_* functions are actually macros.
- This is an example of a dynamic mutex created at run time. You may also use
a static mutex defined at compile time. I have not had good luck in using
static mutexes and find the "dynamic" mutex more usable.
- Considerations when updating GTK+ GUI from a GDK thread
|Yielding processing time:
The GDK thread can communicate with the operating system scheduler to yield
processing time to other threads. This is preferable to a spinning a loop
to delay a thread.
if ( haveExtraTime )
gtk_main_iteration(); // Handle unprocessed GTK events
g_thread_yield(); // Yield processing time
[Potential Pitfall]: When using this
API on Microsoft Windows and compiling with Visual Studio VC++ compiler
be sure to use the proper compiler flag to use the appropriate
If you use the single threaded debug libraries, a call to printf to print local variables may cause a crash.
- Use: /MTd Use debug, multi-threaded, libraries
- DO NOT USE: MLd => Use debug, single-threaded, libraries