Re: GTK and threads



kornelix wrote:
Thanks to the three of you for your help and information. I will continue trying to make GTK work for my threaded application, and post progress (or lack thereof).

I am still confused (by apparently conflicting inputs from the GTK FAQ and yourselves) about when I must use which wrapper calls to force the GDK/GTK functions to single-thread themselves. First, is there a distinction between the main() thread and threads created later with pthread_create(), or should I be following the same rules? I have been making a distinction, and I am thinking this must be wrong.


Posting some code is a good start. I think that the only way to get this solved is to have a complete working (or non-working), compilable source code snippet that illustrates very simply what you are trying to do. Then we can identify the problems. I myself am not experienced enough to deduce the problems solely from the code snippets you have below.

To this end later today I will build a very small C program that I believe will illustrate what you are trying to accomplish. I will have a simple button that, upon clicking, will spawn a thread that will just do something simple, like writing text to the window or something.

Yes the documentation for GTK is lacking in some areas (like the proper ways to do threading and things). However there are many, many good source code examples out there of projects large and small that do work.

Anyway, I will post my example code and findings later today.

Michael



The rules as I understand them now:

Main program:
   g_thread_init(NULL);
   gdk_threads_init();
   gtk_init(&argc, &argv);
     ...
   gdk_threads_enter();                  //  I had omitted this step
   win = gtk_window_new(...);
       ... add some menus to win
   gtk_widget_show_all(win);
   gtk_main();      gdk_threads_leave();

menu event function:
   pthread_create() a response thread

menu response thread: every GTK/GDK function wrapped as follows:
   gdk_threads_enter();
       ... do GTK calls to create / update windows and / or get user input
   gdk_flush();
   gdk_threads_leave();

Signal response functions: always in main() thread, without enter/leave wrapper calls.

Some Glib functions (e.g. idle, timeout): always in main() thread, with enter/leave wrappers.
(I am not using these, so I can live with the ambiguity for now).

Now I am going to harangue you once again about the need for all the above stuff. I hope you will indulge me. I don't recall any counterparts in Win32 to these wrapper functions (gtk/gdk init / enter / leave). Perhaps I am off base, but I think Win32 takes care of its own locking and threading business. I still think GTK should do the same. The GTK user (caller) should not have to single-thread the functions by putting wrappers around the calls. The above rules are simply awful. If GTK must single-thread (some of) its function calls, it should manage this itself.

I have been advised several times to move all GTK calls into the main() thread and keep them out of the created threads. I hope this is not the answer, because this makes the application much more complex. For a simple example: I want to write text to a logging window from multiple threads. I wrote a simple function to do this that works like printf(). To avoid GTK calls from the threads, I would have to create a queue of such messages and have an idle function in main() that checks the queue and updates the window, or (better), have the thread functions send a message to the logging window and have its event function take care of the updates. For more complex cases, e.g. graphic updates or user dialogs, it just gets messier. Am I failing to understand something here?

One of you mentioned that X11 has no thread awareness in its user (caller) protocol. Sounds great to me. Was this a criticism?

The lockup problem I mentioned was definitely GTK. It was repeatable: I started my (faulty) GTK app, selected a menu causing a thread creation with GTK calls, and the whole GNOME desktop froze up. Nothing worked at all, not even a terminal launch from the panel. I had to power off. IIRC, it was the situation depicted above with the missing call to gtk_threads_enter().

<<
You're looking at this in an overly-complicated way. Here are a few guidelines, all of which probably have appropriate documentation somewhere: ...
 >>
Sadly this is the typical state of documentation for Linux and most open-source software. The insider gurus and macho-geeks don't need the documentation, therefore it does not exist, is outdated, is scattered and disorganized, or just wrong. When web forums and e-mail lists are the only support you get, then quality documentation is of the utmost importance. Bill Gates can rest quietly at night. The threat from Linux is only in the imagination of the Linux geeks.

Please do not get angry. Shooting the messange is not the answer. I am an old Windows programmer trying to change his spots. I am no Microsoft fan, and I hope you Linux / open-source geeks can put some brakes on the bullying monopoly. I am fairly geeky myself, but still an infant in the Linux arena, and very grateful for all the help I can get.

regards






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]