G_timeout_add inside GThread

I am trying to add a GThread specific timeout source.

In the main thread, I can create a GMainContext ( g_main_context_new ) and add a timeout ( g_timeout_add ). However, when I try to do this in a thread created with g_thread_create , it just doesn't work, GSourceFunc is never called, and I don't know why.

At the moment, I only have documentation:

Callbacks require little attention. GTK + callbacks (signals) are made in the GTK + lock. However, callbacks from GLib (timeouts, IOs, and idle functions) are performed outside of GTK + lock. Thus, in the signal handler you do not need to call gdk_threads_enter (), but in other types of callbacks you make.

But my timeout function (for testing purposes) prints only on the console, so I donโ€™t think that this is a problem of protecting resources and mutexes.

Stream structure:

Main thread -> no main GLib context explicitly created

  • capture the stream

  • process thread -> must have a main GLib context and a timeout source

  • show stream

I appreciate any help.

Thanks in advance.

+2
multithreading timeout glib
source share
1 answer

Are you g_timeout_add() or g_source_attach() ?

g_timeout_add() and g_timeout_add_full() do not allow you to specify which main context to add. It always uses the default default context. if you do not use the default main context in your main thread, it is quite normal to use it in your process thread . You can read about it in the description .

GMainContext can only work in one thread

The default main context is implicitly created by many functions, including g_main_context_default() . Therefore, please make sure that you do not use it in your main topic.

You can use g_source_attach() to add a timeout source to your main context if you decide to do this. There is no timeout function that you can use to specify the main context. So do it yourself.

The following code is basically the same as: g_timeout_add_full(G_PRIORITY_DEFAULT, 100, func, l, notify);

 #include <glib.h> void notify(gpointer data) { g_main_loop_quit((GMainLoop *)data); } gboolean func(gpointer data) { static gint i = 0; g_message("%d", i++); return (i < 10) ? TRUE : FALSE; } gpointer thread(gpointer data) { GMainContext *c; GMainContext *d; GMainLoop *l; GSource *s; c = g_main_context_new(); d = g_main_context_default(); g_message("local: %p", c); g_message("default: %p", d); #if 1 l = g_main_loop_new(c, FALSE); s = g_timeout_source_new(100); g_source_set_callback(s, func, l, notify); g_source_attach(s, c); g_source_unref(s); #else l = g_main_loop_new(d, FALSE); g_timeout_add_full(G_PRIORITY_DEFAULT, 100, func, l, notify); #endif g_main_loop_run(l); g_message("done"); return NULL; } int main(int argc, char *argv[]) { GError *error = NULL; GThread *t; g_thread_init(NULL); t = g_thread_create(thread, NULL, TRUE, &error); g_thread_join(t); return 0; } 
+1
source share

All Articles