我是靠谱客的博主 独特小蚂蚁,最近开发中收集的这篇文章主要介绍GTK Gossip: GThread,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一個進程(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("按鈕按下:%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所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(33)

评论列表共有 0 条评论

立即
投稿
返回
顶部