免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5253 | 回复: 5
打印 上一主题 下一主题

GTK Threads 問題請教, 急救!! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-08-02 18:23 |只看该作者 |倒序浏览
各位好,
小弟有一個gtk程序, 它會開啟一個thread來作後台控制, 而前台就顯示gtk程序的...
我的程序在運行時會出現錯誤及自動關閉. 請問我的錯誤問題在那裡呢?
請各位指教小弟一下. 謝謝.

test.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <pthread.h>
  4. #include <unistd.h>
  5. #include <gtk/gtk.h>

  6. pthread_mutex_t thr_mutex;
  7. static pthread_t my_thread;

  8. void msg(char *error)
  9. {
  10.     GtkWidget *window = NULL, *dialog_window;

  11.      dialog_window = gtk_message_dialog_new(GTK_WINDOW(window),
  12.             GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
  13.             GTK_MESSAGE_INFO, GTK_BUTTONS_OK, error);
  14.     gtk_dialog_run(GTK_DIALOG(dialog_window));
  15.     gtk_widget_destroy(dialog_window);
  16. }

  17. void window(void)
  18. {
  19.     GtkWidget *window;

  20.     window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  21.     gtk_window_set_title(GTK_WINDOW(window), "GTK Thread Loop");
  22.     gtk_widget_set_usize(window, 300, 200);
  23.     gtk_signal_connect(GTK_OBJECT(window), "destroy", gtk_main_quit, NULL);

  24.     gtk_widget_show_all(window);
  25. }

  26. static void *run(void *none)
  27. {
  28.     int i = 4;
  29.     while(1)
  30.     {
  31.         if(i == 4)
  32.         {
  33.             gdk_threads_enter();
  34.             msg("OK");
  35.             gdk_threads_leave();
  36.         }
  37.     }

  38.     return 0;
  39. }

  40. static void init(void)
  41. {
  42.     pthread_mutex_init(&thr_mutex, NULL);
  43.     pthread_mutex_lock(&thr_mutex);
  44. }

  45. static void start(void)
  46. {
  47.     pthread_create(&my_thread, NULL, run, NULL);
  48. }

  49. int main(int argc, char *argv[])
  50. {
  51.     gtk_init(&argc, &argv);

  52.     window();

  53.     init();
  54.     start();

  55.     gtk_main();
  56.     return 0;
  57. }
复制代码


編譯時用
gcc -o test.c -lpthread `pkg-config --cflags --libs` `pkg-config --cflags --libs gthread-2.0`

請各位指教. thanks.

论坛徽章:
0
2 [报告]
发表于 2006-08-03 08:16 |只看该作者
在GTK+中使用线程,如果线程中涉及到GLIB库和GDK操作,那么必须在gtk_init之前运行
        g_thread_init(NULL);
        gdk_threads_init();

同时,pkg-config参数中要加入--libs gthread-2.0

论坛徽章:
0
3 [报告]
发表于 2006-08-03 22:11 |只看该作者
原帖由 assiss 于 2006-8-3 08:16 发表
在GTK+中使用线程,如果线程中涉及到GLIB库和GDK操作,那么必须在gtk_init之前运行
        g_thread_init(NULL);
        gdk_threads_init();

同时,pkg-config参数中要加入--libs gthread-2.0


你好, 明白. 我是欠了這二個函數...

係呢, 唔知有無咩gtk的電子書呢.

论坛徽章:
0
4 [报告]
发表于 2006-08-08 11:32 |只看该作者
用devhelp不就都搞定!

论坛徽章:
0
5 [报告]
发表于 2006-08-08 17:18 |只看该作者
我这还有稍微具体的介绍
在glib中提供了一个对于线程进行了封装,在国力把中有 Threads 的api。

在编译含有thread的程序的时候,在Makefile中需要使用
`pkg-config --cflags --libs gtk+-2.0 gthread-2.0`

这是因为thread在glib中是可选编译的,如果编译完成之后就会定义 G_THREADS_ENABLED ,
如果在编写线程可选的程序中可以检查这个宏是否定义。

在程序开始的时候,我们需要g_thread_supported(),然后使用g_thread_init(NULL),

在使用任何有关gtk的函数的时候,我们都需要使用gdk_threads_enter()和gdk_threads_leave()
这两个成对的函数。

下面是一个实例:



#include <gtk/gtk.h>  

/*创建的线程: 更改标签文本*/
void thread1(GtkWidget *label){
        int i;
        char str[3];
        for(i=1;i<=10;i++){
                sleep(1);
                sprintf(str,"%d",i);
                gdk_threads_enter();
                gtk_label_set_text(GTK_LABEL(label),str);
                gdk_threads_leave();
        }
}

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

        GtkWidget *window;
        GtkWidget *vbox, *label;

        if(!g_thread_supported()) g_thread_init(NULL);
        gdk_threads_init();

        gtk_init(&argc,&argv);

        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_window_set_title(GTK_WINDOW(window),"thread test");
        g_signal_connect(G_OBJECT(window),"delete_event",
                        G_CALLBACK(gtk_main_quit),NULL);
        gtk_container_set_border_width(GTK_CONTAINER(window),2);

        vbox = gtk_vbox_new(FALSE,0);
        gtk_container_add(GTK_CONTAINER(window),vbox);

        label = gtk_label_new("num");
        gtk_widget_set_size_request (label,50,50);
        gtk_box_pack_start(GTK_BOX(vbox),label,FALSE,FALSE,5);

        gtk_widget_show_all(window);

        g_thread_create(thread1, label, FALSE, NULL);

        gdk_threads_enter();
        gtk_main();
        gdk_threads_leave();

        return FALSE;
}

在编写多线程的程序中,要注意的是全局变量的同步,这里介绍的是使用互斥锁的方法。

gthread中也提供了这方面的封装,

            GMutex;
GMutex*     g_mutex_new                     ();
void        g_mutex_lock                    (GMutex *mutex);
gboolean    g_mutex_trylock                 (GMutex *mutex);
void        g_mutex_unlock                  (GMutex *mutex);
void        g_mutex_free                    (GMutex *mutex);

一般而言,在主线程中对互斥锁进行 new 和 free。
在其他线程中使用,

  if(g_mutex_trylock(mutex) == FALSE)
  {
    临界区操作,尽量不要太复杂。
   g_mutex_unlock(mutex);
  }

如果有什么错误和补充的地方,欢迎讨论。

论坛徽章:
0
6 [报告]
发表于 2006-08-10 11:06 |只看该作者
Thanks. 明白了. 再學習學習.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP