fltk/Threads.h File Reference

#include <fltk/FL_API.h>
#include <pthread.h>

Classes

class  fltk::Guard
class  fltk::Mutex
class  fltk::RecursiveMutex
class  fltk::SignalMutex

Namespaces

namespace  fltk

fltk/Threads.h

typedef pthread_t fltk::Thread
int fltk::create_thread (Thread &t, void *(*f)(void *), void *p)

Detailed Description

Inline classes to provide a "toy" interface for threads and mutexes. These are used by the fltk demo programs. They have been improved quite a bit and may be useful for non-toy programs, too. This file is optional, you can use pthreads or any other multithreading library if you want more control over multithreading.

Warning: on Windows including this will cause the <windows.h> header file to be included. This file often has undesirable effects and should be avoided if at all possible.

How to Multithread FLTK Applications

If you have multiple threads accessing FLTK functions, you must surround any calls to FLTK with fltk::lock() and fltk::unlock() pairs. This is a recursive mutex so you can nest multiple calls to lock/unlock.

Although it appears that whatever thread calls run() has the lock all the time, in fact FLTK releases the lock internally when it waits for events, and then grabs it again before handling the events.

Known problems

The "main" thread is the one that is calling fltk::wait().

If non-main threads want the display to update, besides calling Widget::redraw(), they must call fltk::awake() before calling fltk::unlock(). Otherwise the redraw will not be noticed until the next event comes in, making your program look very sluggish or broken.

Non-main threads cannot call all fltk functions. In particular any functions that wait for events (including fltk::Window::exec(), fltk::check(), and fltk::ask()) do not work. The function fltk::in_main_thread() can be used to check if your code is in the main thread or not (you have to hold the lock to call this). The only workaround is to store what you want to do in static variables, call fltk::awake(), and make the main thread call fltk::wait() repeatedly, checking and acting on the static values after each call.

On Windows you cannot change which thread is the "main" one, and the Window::show() method can only be called by the main thread.

Example

  main() {
    fltk::lock(); // ALWAYS call before any fltk calls
    create_widgets();
    Thread t1; create_thread(t1, func, data1);
    Thread t2; create_thread(t2, func, data2);
    for (;;) {
      fltk::wait();
      check_what_threads_are_up_to();
    }
  }

  fltk::Mutex mutex;

  func1(void* data) {
    mutex.lock();
    do_something();
    mutex.unlock();
    fltk::lock();
    widget->value(foo);
    widget->redraw();
    fltk::awake(); // Without this it may not redraw until next event!
    fltk::unlock();
  }