Re: gtk_timeout_add / SIGALRM with gtk



Colin,
I guess if it is working ok then fine, but I think you'll find it much simpilar to do what you're trying to do if you put the work in the thread and just let the main gtk+ loop take care of keeping your application window fresh.
for example:

void worker_thread( gpointer null )
{

//Large loop to burn cpu time
unsigned int count = 0;
for (
     count = 0;
      count < 100000000;
      count++
      )
{
        // decide if i should update the progress of job in gui
        if( some condition ){
                gdk_threads_enter(); // lock down the main loop
                // update the gui with some information about the progress of this large task
                gdk_threads_leave(); // unlock the main loop
        }
}


}
void on_button_clicked( GtkButton *button, gpointer data )
{
   g_create_thread( worker_thread, NULL , FALSE , NULL);
// return to main loop to allow gtk+ to keep the gui fresh
}

Basically, moving the work into the thread and letting the main thread (i.e. the one that called gtk_main() and on_button_clicked) continue to responde to user inputs. This would make it possible for a user to cancel this large task for example.

volatile gboolean cancel = FALSE;

worker_thread()
{
   for( i = 0; i < 10000000 && !cancel; ++i ){
   }
}

on_cancel_thread()
{
   cancel = TRUE;
}

All, of this threading stuff of course is very sensitive and tends to require a bit of testing on different architectures and different operating systems to be sure you got it right, so above all else keep it simple ;) Of course, if this app is for normal users you probably also need to keep it friendly :)

-todd

Colin Thomas wrote:

Hi Todd,

Apologises for the delay in getting back, but I have been profiling some
code and trying to speed up a routine that is called 1.3 billion times.

What I have done is take you ideas and create a thread to periodically
refresh the main window, which is started and stopped on the enter and
exit of the button being depressed.


i.e.

1. Call back for button being depressed:
========================================
void
on_button_clicked                     (GtkButton       *button,
                                       gpointer         user_data)
{
////////////////////////////////////////
g_mutex_lock(lock);
//Set global flag to mark thread running
working = true;
g_mutex_unlock( lock);

//Start the thread
tid = g_thread_create((GThreadFunc) RunThread, NULL , FALSE , NULL);
////////////////////////////////////////

//Large loop to burn cpu time
unsigned int count = 0;
for (
     count = 0;
      count < 100000000;
      count++
      )
{
}

////////////////////////////////////////
//job finished, inform thread to kill itself
g_mutex_lock(lock);
working = false;
g_mutex_unlock( lock);

//Sleep for the same amount of time as the thread refresh time, to //ensure that the thread sees working as false and dies, before a
//possible 2nd thread is created, and two threads end up running in
//parallel.
g_usleep(500000);       
////////////////////////////////////////
}

2. Function to refresh the main window:
=======================================
void RunThread ()
{
//Thread will die when work set to false (when main job completes)
while(working)
{
gtk_widget_draw (pTOPWindow,NULL); gdk_flush();
 //put thread to sleep for 1/2 sec => refresh every 1/2 sec
 g_usleep(500000);      
}
}

3. Enabling code in main routine:
=================================

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

g_thread_init(NULL);
gdk_threads_init();
gtk_init(&argc, &argv );        
lock = g_mutex_new();   
.
.
.

This seems to be okay.. can you see any possible flaws?

Many thanks again for your help.

Best regards

Colin Thomas






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]