概述
一個進程(Process)是一個包括有自身執行位址的程式,在一個多工的作業系統中,可以分配CPU時間給每一個進程,CPU在片段時間中執行某個進程,然後下一個時間片段跳至另一個進程去執行,由於轉換速度很快,這使得每個程式像是在同時進行處理一般。
一個執行緒是進程中的一個執行流程,一個進程中可以同時包括多個執行緒,也就是說一個程式中同時可能進行多個不同的子流程,這使得一個程式可以像是同時間處理多個事務,例如一方面接受網路上的資料,另一方面同時計算資料並顯示結果,一個多執行緒程式可以同時間處理多個子流程。
在GLib中,提供GThread來實現可攜式的執行緒解決方案,以 內建 Signal 的發射與停止 中的範例來說,當中使用到 pthread,因而只能在 Linux 之類的系統中執行,您可以改寫為使用GThread的方式,例如:
在使用g_thread_create()函式之前,先使用g_thread_supported()函式檢查一下執行緒系統是否已初始化,signal_thread是自訂的callback函式,所建立的GThread會執行該函式,g_usleep()是用來暫停執行緒之用,單位是微秒。
為了編譯這個程式,您必須設定gthread-2.0程式庫路徑資訊,可以使用pkg-config取得這個資訊,例如:
事實上,GThread要在建立GMainLoop下才能使用,MainLoop的目的是等待事件的發生,並呼叫適當的callback函式,在GTK的程式,不用自行建立MainLoop,因為在gtk_init()中已幫您建立,而Main Loop的執行則是在gtk_main()中替您進行。
下面這個範例程式,示範了如何自行建立Main Loop,並建立三個執行緒,其中一個執行緒會執行checking_thread()函式,以檢查另兩個執行緒是否已完成,若已完成則結束Main Loop:
一個執行的結果如下所示:read2: 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("按鈕按下:%sn", (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下才能使用,MainLoop的目的是等待事件的發生,並呼叫適當的callback函式,在GTK的程式,不用自行建立MainLoop,因為在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: %sn", data);
g_usleep(1000000);
}
thread1_end = TRUE;
}
gpointer thread2(gpointer data) {
int i;
for(i = 0; i < 10; i++) {
g_print("Thread2: %sn", 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;
}
一個執行的結果如下所示:read2: 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: GThread的全部内容,希望文章能够帮你解决GTK Gossip: GThread所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复