GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Sun Aug 30, 2015 1:57 pm

All times are UTC




Post new topic Reply to topic  [ 1 post ] 
Author Message
 Post subject: Lazy Loading and Threads
PostPosted: Fri Jul 17, 2015 11:05 pm 
Offline
GTK+ Guru

Joined: Sat Jul 26, 2014 11:43 pm
Posts: 192
I have been looking at lazy loading data and using threads. It looks like if you use lazy loading, once the program enters the function, it still will lock up the UI if the function is a long running function. Work is being done on a single thread so that makes sense. Lazy loading will work if I can break a function down into small enough pieces that the work can be done quickly on each piece.

I have got a couple of potentially long running calculations that I don't think that I will be able to break them down into smaller pieces. Namely a permutation function and a multivariate numerical integration function. It is looking like threads are a better choice for this.

Not much of a threading expert and trying to improve my skillset here. If I am using anything inappropriately in the following test code I would appreciate hearing about it. It would help me out greatly. Thank you.

Eric

Code:
//gcc -Wall progress2.c -o progress2 `pkg-config --cflags --libs gtk+-3.0`

#include<gtk/gtk.h>

//Set some loops for work to be done. Using a netbook with a Atom N270 cpu. Might need to
//change these for a faster cpu but be careful of guint overflow.
#define SET1 1000000000
#define SET2 100000000
//Number of times the lazy load functions get called. 10 times 100 million in this case.
#define CALLS 10

gint load_progress=0;
//The thread_active variable is used for both lazy_load_items and thread_load_items functions.
//It tells the timer used for the progress bar when to stop.
gint thread_active=0;
GThread *thread=NULL;

static int thread_load_items(gpointer data)
  {
    guint32 i=0;
    gdouble percent=0;   
   
    for(i=0;i<SET1;i++)
      {
        if(i%SET2==0)
          {
            g_print("progress %f\n", (gdouble)i/SET1);
            percent=(gdouble)(i+1)/SET1;
            g_atomic_int_set(&load_progress, (gint)(percent*100));
          }
      }
   
    g_print("Items Loaded\n");
    g_atomic_int_set(&thread_active, 0); 
    return 0;   
  }
static gboolean lazy_load_items(gpointer data)
  {
    guint32 i=0;
    guint32 top=0;
    gdouble percent=0;   
    static guint32 counter=0;

    top=SET2*counter+SET2;

    for(i=SET2*counter;i<top;i++)
      {       
        //Try to match work done in threaded code.
        if(i%SET2==0)
          {
          }
      }

    g_print("progress %f\n", (gdouble)i/SET1);
    percent=(gdouble)(i+1)/SET1;
    g_atomic_int_set(&load_progress, (gint)(percent*100));
    counter++; 
    if(counter==CALLS)
      {
        g_atomic_int_set(&thread_active, 0);
        counter=0;
        g_print("Items Loaded\n"); 
        return FALSE;
      }
    else return TRUE;   
  }
static gboolean check_progress(gpointer data)
  {
    g_print("Check Progress\n");
    gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(data), (gdouble)(g_atomic_int_get(&load_progress)/100.0));
    gchar *string1=g_strdup_printf("progress %i%%\n", g_atomic_int_get(&load_progress));
    gtk_progress_bar_set_text(GTK_PROGRESS_BAR(data), string1);
    g_free(string1);
 
    if(g_atomic_int_get(&thread_active)==1)
      {
        return TRUE;
      }
    else
      {
        gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(data), 0);
        gchar *string2=g_strdup_printf("progress %i%%\n", 0);
        gtk_progress_bar_set_text(GTK_PROGRESS_BAR(data), string2);
        g_free(string2);
        gtk_widget_hide(GTK_WIDGET(data));
        g_atomic_int_set(&load_progress, 0);
        if(thread!=NULL)
          {
            //Make sure the thread returned. Also freed.
            g_print("Thread Return %i\n", (int)g_thread_join(thread));
            thread=NULL;
          }
        return FALSE;
      }
  }
static void show_progress(GtkWidget *widget, gpointer data[])
  { 
    gtk_widget_show(GTK_WIDGET(data[0]));
    g_atomic_int_set(&thread_active, 1);

    if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data[1])))
      {
        g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, lazy_load_items, data[0], NULL);
      }
    else
      {
        thread=g_thread_new("TestThread", (GThreadFunc)thread_load_items, data[0]);
      }
   
    g_timeout_add(500, check_progress, data[0]);     
  }
int main(int argc, char *argv[])
  {
    gtk_init(&argc, &argv);

    GtkWidget *window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "Show Progress");
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(window), 200, 200);
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    GtkWidget *progress=gtk_progress_bar_new();
    gtk_widget_set_hexpand(progress, TRUE);
    gtk_widget_set_vexpand(progress, TRUE);
    gtk_progress_bar_set_show_text(GTK_PROGRESS_BAR(progress), TRUE);

    GtkWidget *radio1=gtk_radio_button_new_with_label(NULL, "Lazy Load");
    GtkWidget *radio2=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(radio1), "Thread");
    gpointer widgets[]={progress, radio1, radio2};

    GtkWidget *button=gtk_button_new_with_label("Show Progress");
    gtk_widget_set_hexpand(button, TRUE);
    g_signal_connect(button, "clicked", G_CALLBACK(show_progress), widgets);

    GtkWidget *grid=gtk_grid_new();
    gtk_grid_attach(GTK_GRID(grid), radio1, 0, 0, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), radio2, 0, 1, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), button, 0, 2, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), progress, 0, 3, 1, 1);
    gtk_container_add(GTK_CONTAINER(window), grid);

    gtk_widget_show_all(window);
    gtk_widget_hide(progress);
    gtk_main();
    return 0;   
  }


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group