GTK Gossip: GThread
2010-12-10 15:26
267 查看
一個進程(Process)是一個包括有自身執行位址的程式,在一個多工的作業系統中,可以分配CPU時間給每一個進程,CPU在片段時間中執行某個進程,然後下一個時間片段跳至另一個進程去執行,由於轉換速度很快,這使得每個程式像是在同時進行處理一般。
一個執行緒是進程中的一個執行流程,一個進程中可以同時包括多個執行緒,也就是說一個程式中同時可能進行多個不同的子流程,這使得一個程式可以像是同時間
處理多個事務,例如一方面接受網路上的資料,另一方面同時計算資料並顯示結果,一個多執行緒程式可以同時間處理多個子流程。
在GLib中,提供GThread來實現可攜式的執行緒解決方案,以
內
建 Signal 的發射與停止
中的範例來說,當中使用到 pthread,因而只能在 Linux 之類的系統中執行,您可以改寫為使用GThread的方式,例如:
gthread_demo.c
在使用g_thread_create()函式之前,先使用g_thread_supported()函式檢查一下執行緒系統是否已初始化,
signal_thread是自訂的callback函式,所建立的GThread會執行該函式,g_usleep()是用來暫停執行緒之用,單位是微
秒。
為了編譯這個程式,您必須設定gthread-2.0程式庫路徑資訊,可以使用pkg-config取得這個資訊,例如:
pkg-config --libs gthread-2.0
事實上,GThread要在建立GMainLoop下才能使用,Main
Loop的目的是等待事件的發生,並呼叫適當的callback函式,在GTK的程式,不用自行建立Main
Loop,因為在gtk_init()中已幫您建立,而Main Loop的執行則是在gtk_main()中替您進行。
下面這個範例程式,示範了如何自行建立Main Loop,並建立三個執行緒,其中一個執行緒會執行checking_thread()函式,以檢查另兩個執行緒是否已完成,若已完成則結束Main Loop:
gthread_demo.c
一個執行的結果如下所示:
Thread1: Running
Thread2: Going
Thread2: Going
Thread1: Running
Thread1: Running
Thread2: Going
Thread2: Going
Thread1: Running
Thread1: Running
Thread2: Going
Thread1: Running
Thread2: Going
Thread2: Going
Thread1: Running
Thread2: Going
Thread1: Running
Thread1: Running
Thread2: Going
Thread1: Running
Thread2: Going
一個執行緒是進程中的一個執行流程,一個進程中可以同時包括多個執行緒,也就是說一個程式中同時可能進行多個不同的子流程,這使得一個程式可以像是同時間
處理多個事務,例如一方面接受網路上的資料,另一方面同時計算資料並顯示結果,一個多執行緒程式可以同時間處理多個子流程。
在GLib中,提供GThread來實現可攜式的執行緒解決方案,以
內
建 Signal 的發射與停止
中的範例來說,當中使用到 pthread,因而只能在 Linux 之類的系統中執行,您可以改寫為使用GThread的方式,例如:
gthread_demo.c
#include <gtk/gtk.h> gpointer signal_thread(gpointer arg) { int i; for(i = 0; i < 5; i++) { g_usleep(1000000); // 暫停一秒 g_signal_emit_by_name(arg, "clicked"); } } // 自訂Callback函式 void button_clicked(GtkWidget *button, gpointer data) { g_print("按鈕按下:%s/n", (char *) data); } int main(int argc, char *argv[]) { GtkWidget *window; GtkWidget *button; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "哈囉!GTK+!"); button = gtk_button_new_with_label("按我"); gtk_container_add(GTK_CONTAINER(window), button); g_signal_connect(GTK_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); g_signal_connect(GTK_OBJECT(button), "clicked", G_CALLBACK(button_clicked), "哈囉!按鈕!"); gtk_widget_show(window); gtk_widget_show(button); if(!g_thread_supported()) { g_thread_init(NULL); } g_thread_create(signal_thread, button, FALSE, NULL); gtk_main(); return 0; }
在使用g_thread_create()函式之前,先使用g_thread_supported()函式檢查一下執行緒系統是否已初始化,
signal_thread是自訂的callback函式,所建立的GThread會執行該函式,g_usleep()是用來暫停執行緒之用,單位是微
秒。
為了編譯這個程式,您必須設定gthread-2.0程式庫路徑資訊,可以使用pkg-config取得這個資訊,例如:
pkg-config --libs gthread-2.0
事實上,GThread要在建立GMainLoop下才能使用,Main
Loop的目的是等待事件的發生,並呼叫適當的callback函式,在GTK的程式,不用自行建立Main
Loop,因為在gtk_init()中已幫您建立,而Main Loop的執行則是在gtk_main()中替您進行。
下面這個範例程式,示範了如何自行建立Main Loop,並建立三個執行緒,其中一個執行緒會執行checking_thread()函式,以檢查另兩個執行緒是否已完成,若已完成則結束Main Loop:
gthread_demo.c
#include <gtk/gtk.h> gboolean thread1_end = FALSE; gboolean thread2_end = FALSE; gpointer thread1(gpointer data) { int i; for(i = 0; i < 10; i++) { g_print("Thread1: %s/n", data); g_usleep(1000000); } thread1_end = TRUE; } gpointer thread2(gpointer data) { int i; for(i = 0; i < 10; i++) { g_print("Thread2: %s/n", data); g_usleep(1000000); } thread2_end = TRUE; } gpointer checking_thread(gpointer mloop) { while(TRUE) { if(thread1_end && thread2_end) { g_main_loop_quit(mloop); break; } g_usleep(1000); } } int main(int argc, char *argv[]) { GMainLoop *mloop; if(!g_thread_supported()) { g_thread_init(NULL); } mloop = g_main_loop_new(NULL, FALSE); g_thread_create(thread1, "Running", FALSE, NULL); g_thread_create(thread2, "Going", FALSE, NULL); g_thread_create(checking_thread, mloop, FALSE, NULL); g_main_loop_run(mloop); return 0; }
一個執行的結果如下所示:
Thread1: Running
Thread2: Going
Thread2: Going
Thread1: Running
Thread1: Running
Thread2: Going
Thread2: Going
Thread1: Running
Thread1: Running
Thread2: Going
Thread1: Running
Thread2: Going
Thread2: Going
Thread1: Running
Thread2: Going
Thread1: Running
Thread1: Running
Thread2: Going
Thread1: Running
Thread2: Going
相关文章推荐
- GTK Gossip: GTK 的物件導向架構
- GTK Gossip: GtkMessageDialog
- GTK Gossip: GtkAlignment、GtkFixed 與 GtkLayout
- GTK Gossip: GtkDrawingArea
- GTK Gossip: 使用 Signal 关闭视窗
- GTK Gossip: GLib 基本型態與巨集
- GTK Gossip: 自訂 callback 函式
- GTK Gossip: GtkColorButton 與 GtkColorSelectionDialog
- GTK Gossip: GtkHandleBox
- GTK Gossip: GTimer
- GTK Gossip: 內建 Signal 的發射與停止
- GTK Gossip: GtkFontButton 與 GtkFontSelectionDialog
- GTK Gossip: GtkMenuBar、GtkMenu 與 GtkMenuItem
- GTK Gossip: 環境資訊
- GTK Gossip: GtkSpinButton
- GTK Gossip: GDK 事件結構
- GTK Gossip: GtkFileChooserButton 與 GtkFileChooserDialog
- GTK Gossip: 日誌(Logging)
- GTK Gossip: 基本檔案讀寫
- GTK Gossip: GtkScrolledWindow