一般 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`