GTK+中文社区(gtk.awaysoft.com)

 找回密码
 马上加入

QQ登录

只需一步,快速开始

查看: 3402|回复: 0

gthread使用注意

[复制链接]
  • TA的每日心情
    奋斗
    2016-10-11 09:20
  • 签到天数: 271 天

    连续签到: 1 天

    [LV.8]以坛为家I

    发表于 2011-7-11 01:25:05 | 显示全部楼层 |阅读模式
    转自:http://blog.csdn.net/c_spark/article/details/4742919

    1、初始化gthread
          if (!g_thread_supported ()) //如果gthread没有被初始化
                 g_thread_init (NULL);  //进行初始化
          gdk_threads_init ();        //初始化GDK多线程,这样可以在多线程中使用成对的gdk_threads_enter()和gdk_thread_leave(),在Gtk程序保证          gdk_threads_init()在main loop执行之前执行,为了保证线程安全应该在gtk_init()之前调用,g_thread_init()必须在函数gdk_threads_init()之前执行。
    2、gdk_threads_enter()和gdk_threads_leave()
       gdk_threads_enter()这是一宏定义,占领临界区,这样使Gdk和Gtk+函数在多线程中被安全的调用而不会造成竞争条件,保证数据安全,一次只能有一线程访问临界区。gdk_threads_leave释放对当前临界区访问。
         在调用任何与gtk相关函数时,需要使用gdk_threads_enter()和gdk_threads_leave()成对的宏,保证当前函数的的调用只可能在一个线程中。
    3、示例如下:


    1. #include <glib.h>  
    2.     #include <gtk/gtk.h>  
    3.     #include <libgnomevfs/gnome-vfs.h>  
    4.     #define BUF_SIZE 4096  
    5.     GtkWidget *window;  
    6.     GtkWidget *image = NULL;  
    7.     GtkWidget *vbox = NULL;  
    8.     const gchar *uri = "/home/cspark/logo-large.png";  
    9.     void callback (void)  
    10.     {  
    11.         g_print ("%d %s/n", __LINE__, __FUNCTION__);  
    12.     }  
    13.       
    14.     void   
    15.     thread_func (GtkWidget *button)  
    16.     {  
    17.         int i;  
    18.         for (i = 0; i <= 20; i++)  
    19.         {  
    20.             sleep (1);  
    21.             gchar *s = g_strdup_printf ("Test %d", i);  
    22.             gdk_threads_enter ();  
    23.             gtk_button_set_label (GTK_BUTTON (button), s);  
    24.             gdk_threads_leave ();  
    25.             if (s) {  
    26.                 g_free (s);  
    27.                 s = NULL;  
    28.             }  
    29.         }  
    30.     }  
    31.     void  
    32.     load_image ()  
    33.     {  
    34.         GnomeVFSHandle *handle;  
    35.         GnomeVFSResult result;  
    36.         GdkPixbufLoader *loader;  
    37.         GdkPixbuf *pixbuf;  
    38.         gchar buffer[BUF_SIZE];  
    39.         GnomeVFSFileSize bytes_read;  
    40.         result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);  
    41.          
    42.         loader = gdk_pixbuf_loader_new ();  
    43.          
    44.         while (result == GNOME_VFS_OK) {  
    45.             result = gnome_vfs_read (handle, buffer,  
    46.                                      BUF_SIZE, &bytes_read);  
    47.             gdk_pixbuf_loader_write (loader, buffer, bytes_read, NULL);  
    48.             sleep (2);  
    49.         }     
    50.         gdk_pixbuf_loader_close (loader, NULL);  
    51.         pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);  
    52.       
    53.         if (!pixbuf) {  
    54.             g_print ("pixbuf is NULl");  
    55.             return;  
    56.         }  
    57.         gdk_threads_enter ();  
    58.         image = gtk_image_new_from_pixbuf (pixbuf);  
    59.         gtk_box_pack_start (GTK_BOX (vbox), image, FALSE, FALSE, 0);  
    60.         gtk_widget_show (image);  
    61.         gdk_threads_leave ();  
    62.     }  
    63.     int main (int argc, char *argv[])  
    64.     {  
    65.         if (!g_thread_supported ())  
    66.             g_thread_init (NULL);  
    67.         gdk_threads_init();  
    68.         gdk_threads_enter ();  
    69.         gtk_init (&argc, &argv);  
    70.          
    71.         gnome_vfs_init ();  
    72.          
    73.         window = gtk_window_new (GTK_WINDOW_TOPLEVEL);  
    74.          
    75.         g_signal_connect (window, "destroy", gtk_main_quit, NULL);  
    76.         GtkWidget *button = NULL;  
    77.         button = gtk_button_new_with_label ("Test Mutilate GThread");  
    78.         vbox = gtk_vbox_new (FALSE, 0);  
    79.         gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);  
    80.         g_signal_connect (button, "clicked", (GCallback)(callback), NULL);  
    81.         gtk_widget_show (button);  
    82.         gtk_container_add (GTK_CONTAINER (window), vbox);  
    83.         gtk_widget_show_all (window);  
    84.          
    85.         g_thread_create ((GThreadFunc) (load_image), NULL, FALSE, NULL);  
    86.         g_thread_create ((GThreadFunc) (thread_func), button, FALSE, NULL);  
    87.         gtk_main ();  
    88.         gdk_threads_leave ();  
    89.         return 0;     
    90.     }
    复制代码



    Makefile:

    view plain
    1. CC=gcc  
    2.     CFLAGS =  `pkg-config --cflags gtk+-2.0 gthread-2.0 gnome-vfs-2.0` -g  
    3.     LDFLAGS =  `pkg-config --libs gtk+-2.0 gthread-2.0 gnome-vfs-2.0` -rdynamic   
    4.     SRC=gnomevfs-test.c  
    5.     test:$(SRC)  
    6.         $(CC) $(CFLAGS) $(LDFLAGS) $(SRC) -o test
    复制代码
    *滑块验证:
    您需要登录后才可以回帖 登录 | 马上加入

    本版积分规则

    申请友链|Archiver|小黑屋|手机版|GTK+中文社区 ( 粤ICP备13080851号 )

    我要啦免费统计

    GMT+8, 2024-3-29 21:10 , Processed in 0.021833 second(s), 7 queries , Redis On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表