一般 GUI 应用程序默认只有一个执行线程, 每次只执行一个操作, 如果某个操作耗时较长, 则用户界面会出现冻结的现象

   所以若某个操作的时间比较长一般会创建线程去处理

   GTK+应用程序中创建多线程

        除了通过 POSIX 线程函数 pthread_create() 创建线程外 ,实际编程时 ,还可以通过 GTK+ 线程函数 g_thread_create()创建一个线程

   注意:GTK 的界面相关的代码不是线程安全函数

        因此在新线程中执行图形绘制相关的代码时, 需要用函数 gdk_threads_enter()和 gdk_threads_leave()对GTK+代码进行包装, 以保证对 GTK 界面的操作是互斥的

  注意:

      gtk 中使用多线程需进行相应初始化。 并且编译时需要链接 GTK 线程库 -lgthread-2.0

#include <gtk/gtk.h>
#include <glib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

gpointer deal_thread();
gpointer deal_thread1(gpointer data);
void gtk_thread_init(void);

int main(int argc, char *argv[])
{
    gtk_thread_init();

    gtk_init(&argc, &argv);
    //创建新窗口
    GtkWidget *window = NULL;
    GtkWidget *vbox = NULL;

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "thread number");
    gtk_widget_set_size_request(window, 200, 60);
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    vbox = gtk_vbox_new(TRUE, 5);
    gtk_container_add(GTK_CONTAINER(window), vbox);

    //标签
    GtkWidget *label = gtk_label_new("");
    GtkWidget *labell = gtk_label_new("");

    gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 5);
    gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 5);

    /*
     *功能:
     *  创建线程函数
     *参数:
     *  func:线程执行的外部函数
     *  data:传给该外部函数的参数
     *  joinable:标志线程是否可分离
     *  error:出错代码返回地址
     *GThread *g_thread_create(GThreadFunc func,
     *                         gpointer data,
     *                         gboolean joinable,
     *                         GError **error);
     *
     */
    g_thread_create((GThreadFunc)deal_thread, label, FALSE, NULL);
    g_thread_create((GThreadFunc)deal_thread1, label1, FALSE, NULL);

    //pthread_t tid, tid1;
    //pthread_create(&tid, NULL, deal_thread, label);
    //pthread_create(&tid1, NULL, deal_thread1, label1);

    //显示所有控件
    gtk_widget_show_all(window);

    gtk_main();
    return 0;
}

//线程处理
gpointer deal_thread()
{
    int i = 0;
    while(1)
    {
        char buf[20] = "";
        sprintf(buf, "%d", i++);
        printf("i = %d\n", i);
        
        usleep(500 * 1000);
        //使用gdk_thread_*()刷新界面
        //进入多线程互斥
        gdk_thread_enter();
        stk_label_set_text(GTK_LABEL(data),buf);
        //退出多线程互斥
        gdk_thread_leave();
    }
}

gpointer deal_thread1(gpointer data)
{
    int k = 10;
    
    while(1)
    {
        char buf[20] = "";
        
        sprintf(buf, "%d", k++);
        printf("k = %d\n", k);
        sleep(1);

        //进入多线程互斥
        gdk_thread_enter();
        gtk_label_set_text(GTK_LABEL(data), buf);
        //退出多线程互斥
        gdk_thread_leave();
    }
}

void gtk_thread_init(void)
{
    if(FALSE == g_thread_supported())
    {
        g_thread_init(NULL);
    }

    gdk_threads_init();
}

错误: 

       fatal error: gtk/gtk.h: No such file or directory #include <gtk/gtk.h>

       Failed to load module "canberra-gtk-module"


locate libcanberra-gtk-module.so

sudo ln -s /usr/lib/x86_64-linux-gnu/gtk-3.0/modules/libcanberra-gtk-module.so /usr/lib/libcanberra-gtk-module.so

gcc gtk.c `pkg-config --cflags --libs gtk+-2.0`