> [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