[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);
}
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to