您的位置:首页 > 编程语言 > Go语言

GTK Gossip: GThread

2010-12-10 15:26 267 查看
一個進程(Process)是一個包括有自身執行位址的程式,在一個多工的作業系統中,可以分配CPU時間給每一個進程,CPU在片段時間中執行某個進程,然後下一個時間片段跳至另一個進程去執行,由於轉換速度很快,這使得每個程式像是在同時進行處理一般。

一個執行緒是進程中的一個執行流程,一個進程中可以同時包括多個執行緒,也就是說一個程式中同時可能進行多個不同的子流程,這使得一個程式可以像是同時間
處理多個事務,例如一方面接受網路上的資料,另一方面同時計算資料並顯示結果,一個多執行緒程式可以同時間處理多個子流程。

在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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: