> [email protected] wrote:
> > Hello,
> > What is the best way to add a delay function in a thread created with 
> > fl_create_thread for  FLTK 1.1.8 under win32? I'd like the GUI response to 
> > run smoothly even when the delay is running.
> >
> > I need the delays to be in the 20ms-200ms range and it's not critical to be 
> > accurate. The goal of the delay is just not to make the CPU give all its 
> > processing power in a while loop.
> >
> > I experimented with SleepEx() in the fct_with_loop and don't understand 
> > totally how come it affects threads other than the one it is in.In my 
> > bigger program, I created before running fct_wit_loop and the GUI response 
> > is pretty sluggish.
>
>       Here's a program I whipped up this morning that uses a technique
>       I like to use, where I interrupt the FLTK event loop every .10 secs
>       to check for data from the child thread. Child thread never touches
>       FLTK, just streams data into an array that the FLTK thread 
> locks/reads/empties/unlocks.
>
>       Builds on windows and linux:
>
>
> // demo use of FLTK with threads and locking under high load - erco 11/11/10
> #include <FL/Fl.H>
> #include <FL/Fl_Double_Window.H>
> #include <FL/Fl_Multi_Browser.H>
> #include <stdio.h>
> #include <errno.h>
>
> #include <string>
> #include <vector>
> using namespace std;
>
> #ifdef _WIN32
> //
> // WINDOWS
> //
> #include <windows.h>
> #include <process.h>
> #define popen         _popen
> #define pclose                _pclose
> #define COMMAND       "dir /s c:\\windows"
> #define SYSERR                strerror(errno)
> #define SLEEP()               //Sleep(1)                      // unneeded
> #define INITLOCK()    InitializeCriticalSection(&G_lock);
> #define LOCK()                EnterCriticalSection(&G_lock);
> #define UNLOCK()      LeaveCriticalSection(&G_lock);
> #define START_THREAD(f,p) {                                                   
>         \
>                             unsigned long thread_id;                          
>         \
>                             HANDLE thread_h = CreateThread(NULL,              
>         \
>                                                            0,                 
>         \
>                                                            
> (LPTHREAD_START_ROUTINE)f, \
>                                                            (LPVOID)p,         
>         \
>                                                            0,                 
>         \
>                                                            &thread_id);       
>         \
>                         }
> CRITICAL_SECTION G_lock;                      // global lock
> #else
> //
> // UNIX
> //
> #include <unistd.h>
> #include <pthread.h>
> #define COMMAND       "ls -laR /usr"
> #define SYSERR                strerror(errno)
> #define SLEEP()               //usleep(10)                    // unneeded
> #define INITLOCK()    pthread_mutex_init(&G_lock, NULL);
> #define LOCK()                pthread_mutex_lock(&G_lock);
> #define UNLOCK()      pthread_mutex_unlock(&G_lock);
> #define START_THREAD(f,p) {                                                   
>         \
>                             pthread_t thread;                                 
>         \
>                             pthread_create((pthread_t*)&thread, 0, f, 
> (void*)p);      \
>                         }
> pthread_mutex_t G_lock;                               // global lock
> #endif
>
> vector<string> G_lines;                               // lines of output from 
> child thread -> main thread
>
> void* ChildThread(void *) {
>     char s[1024];
>
>     // RUN A COMMAND, AND ADD ITS OUTPUT TO BROWSER
>     FILE *fp = popen(COMMAND, "r");
>     if ( fp == NULL ) {
>       sprintf(s, "ERROR: '%s': %s", (const char*)COMMAND, (const 
> char*)SYSERR);
>
>         LOCK();
>       G_lines.push_back(string(s));
>         UNLOCK();
>
>       return(0);
>     }
>     while ( fgets(s, 1023, fp) ) {
>         LOCK();
>       G_lines.push_back(string(s));
>         UNLOCK();
>       SLEEP();
>     }
>     pclose(fp);
>
>     LOCK();
>     G_lines.push_back("*** DONE");
>     UNLOCK();
>
>     return(0);
> }
>
> int main() {
>
>     // Build FLTK interface
>     Fl_Double_Window *win  = new Fl_Double_Window(600,800);
>     Fl_Multi_Browser *brow = new Fl_Multi_Browser(10,10,600-20,800-20);
>     brow->textfont(FL_COURIER);
>     win->resizable(brow);
>     win->show();
>
>     // Set up child thread to feed us data
>     //    Let child use as much cpu as it wants to fill the G_data array.
>     //    FLTK will grab some cpu every .10 secs to check for new data
>     //    and will update it when it can.
>     //
>     Fl::lock();
>     INITLOCK();
>     START_THREAD(ChildThread, 0);
>
>     // Event loop
>     //    Let FLTK do its thing, but every .10 secs, check for new
>     //    data from child thread.
>     //
>     while ( 1 ) {
>         Fl::wait(.10);
>       if ( ! win->visible() ) break;          // user closed window?
>       LOCK();
>       {
>           for ( unsigned int t=0; t<G_lines.size(); t++ ) {
>               brow->add(G_lines[t].c_str());
>           }
>           G_lines.clear();
>       }
>       UNLOCK();
>     }
>     return(0);
> }

I am going to fully analyze this. I just wanted to point out that Sleep() under 
Windows (I have Win 7 now, but I noticed this with SleepEx on Win XP) stops the 
calls from writing to widgets from working properly in my below test code in 
the sense that I must move the mouse for the widgets to refresh on the screen. 
The add_timeout works.  This test program just counts like a clock, ticking 
every second. My ultimate goal is just to do

while allDataNotReceived==1
{
pollData()....
SleepLightWeightFunctionThatDoesNotSlowOrStopFLTKGuiUpdates()
}

So here's the code that shows Win32 Sleep() to misbehave:


// generated by Fast Light User Interface Designer (fluid) version 1.0108

#include "main.h"
#include "windows.h"
#include "threads.h"
Fl_Thread thread0;

Fl_Double_Window *window_main=(Fl_Double_Window *)0;

Fl_Value_Output *clockValueOutput=(Fl_Value_Output *)0;

int main(int argc, char **argv) {
  { window_main = new Fl_Double_Window(291, 151, "FLTK window");
    window_main->align(FL_ALIGN_CLIP|FL_ALIGN_INSIDE);
    { clockValueOutput = new Fl_Value_Output(130, 16, 57, 24, "clock");
      clockValueOutput->value(1);
    } // Fl_Value_Output* clockValueOutput
    window_main->end();
  } // Fl_Double_Window* window_main
  Fl::lock();  /*This is necessary to use here before the Fl::run()  because it 
will set up the run mechanism*/



//Fl::add_timeout( 1, clockFn);


fl_create_thread(thread0, NeedToMoveMouse , 0);
  window_main->show(argc, argv);
  return Fl::run();
}

void * NeedToMoveMouse( void *p) {
  while (1==1)

{

clockValueOutput->value(clockValueOutput->value() +1);

Sleep(1000);



}
}

void clockFn( void *p) {
  clockValueOutput->value(clockValueOutput->value() +1);

Fl::repeat_timeout( 1, clockFn);
}

_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to