根據該documentation,主甚至環可以從不同的線程接受來源:
甲GMainContext只能在單個線程中運行,但源可以 可以從添加到它併除去從它其他線程。
所以,你可以從你的工作線程注入在UI線程的代碼:
- 創建
GSource
(例如,通過使用g_idle_source_new
);
- 將您想要執行的代碼添加到
g-source-set-callback
;
- 用
g_source_attach()
將它附加到UI線程上下文中。
這裏是GTK + 2和GLib的一個樣本程序> = 2.32:
#include <gtk/gtk.h>
#define N_THREADS 100
#define N_ITERATIONS 100
GtkWidget *bar;
GMainContext *context;
static gboolean
update_progress_bar(gpointer user_data)
{
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(bar),
g_random_double_range(0, 1));
return G_SOURCE_REMOVE;
}
static gpointer
thread_func(gpointer user_data)
{
int n_thread = GPOINTER_TO_INT(user_data);
int n;
GSource *source;
g_print("Starting thread %d\n", n_thread);
for (n = 0; n < N_ITERATIONS; ++n) {
/* If you want to see anything you should add a delay
* to let the main loop update the UI, e.g.:
* g_usleep(g_random_int_range(1234, 567890));
*/
source = g_idle_source_new();
g_source_set_callback(source, update_progress_bar, NULL, NULL);
g_source_attach(source, context);
g_source_unref(source);
}
g_print("Ending thread %d\n", n_thread);
return NULL;
}
gint
main(gint argc, gchar *argv[])
{
GtkWidget *window;
GThread *thread[N_THREADS];
int n;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
bar = gtk_progress_bar_new();
gtk_container_add(GTK_CONTAINER(window), bar);
context = g_main_context_default();
for (n = 0; n < N_THREADS; ++n)
thread[n] = g_thread_new(NULL, thread_func, GINT_TO_POINTER(n));
gtk_widget_show_all(window);
gtk_main();
for (n = 0; n < N_THREADS; ++n)
g_thread_join(thread[n]);
return 0;
}
來源
2015-01-16 18:42:14
ntd
你有如何做到這一點的例子用一個簡單的GTK + pthreads設置?謝謝! – DevNull
@Dogbert剛剛添加到答案。 – ntd
謝謝。這與我的原始問題意義最接近。 – DevNull