Classes | |
| class | Guard |
| class | Mutex |
| class | RecursiveMutex |
| class | SignalMutex |
Typedefs | |
| typedef pthread_t | fltk::Thread |
Functions | |
| void | fltk::awake (void *message=0) |
| int | fltk::create_thread (Thread &t, void *(*f)(void *), void *p) |
| bool | fltk::in_main_thread () |
| void | fltk::lock () |
| void * | fltk::thread_message () |
| void | fltk::unlock () |
The "main" thread is the one that calls fltk::wait(). It should call fltk::lock() immediately and then never call fltk::unlock(). Though it appears that fltk is then locked all the time, it is in fact unlocked while fltk::wait() is waiting for events, which is really the majority of the time.
If non-main threads cause any fltk::Widget::redraw() calls, they should call fltk::awake() just before fltk::unlock(). Otherwise the drawing may not be done until the next event.
Non-main threads cannot call all fltk functions. In particular any functions that wait for events (including fltk::Window::exec() and fltk::ask()) do not work. On Windows fltk::Window::show() does not work either. It it likely we will be fixing these in the future. To make these broken calls you will have to store the fact that you want them called in static memory locations, then call fltk::awake() to make the main thread return, and have it check the static locations and do the calls.
FLTK provides the file <fltk/Threads.h> which defines some convenience portability wrappers around the native threads system. It provides a Thread type and the classes Mutex and SignalMutex. This file is optional. Fltk does not use it (it has an internal mutex implementation). The header file's only purpose is so we can write portable demo programs. It may be useful or an inspiration to people who want to try writing multithreaded programs themselves, however you can instead use pthreads or any other library that is compatable with your system.
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();
}
Warning: on Windows including <fltk/Threads.h> will cause the <windows.h> header file to be included. This file often has undesirable effects and should be avoided if possible.
|
|
Hides whatever the system uses to identify a thread. Used so the "toy" interface is portable. |
|
|
A multi-threaded fltk program must surround all calls to any fltk functions with lock() and unlock() pairs. This is a "recursive lock", a thread can call lock() n times, and it must call unlock() n times before it really is unlocked. If another thread calls lock() while it is locked, it will block (not return from lock()) until the first thread unlocks. The main thread must call lock() once before any call to fltk to initialize the thread system. The X11 version of fltk uses XInitThreads(), XLockDisplay(), and XUnlockDisplay(). This should allow an fltk program to cooperate with other packages updating the display using Xlib calls. |
|
|
Releases the lock that was set using the fltk::lock() method. Child threads should call this method as soon as they are finished accessing FLTK. If some other thread is waiting for fltk::lock() to return, it will get control. |
|
|
A child thread can call this to cause the main thread's call to wait() to return (with the lock locked) even if there are no events ready. The main purpose of this is to get the main thread to redraw the screen, but it will also cause fltk::wait() to return so the program's code can do something. You should call this immediately before fltk::unlock() for best performance. The message argument can be retrieved by the other thread using fltk::thread_message(). |
|
|
Returns an argument sent to an awake call, or returns null if none. Warning: the current implementation only has a one-entry queue and only returns the most recent value! |
|
|
Returns true if the current thread is the main thread, i.e. the one that called wait() first. Many fltk calls such as wait() will not work correctly if this is not true. Notice that this function must be surrounded by lock() and unlock() just like all other fltk functions. |
|
||||||||||||||||
|
Fork a new thread and make it run f(p). Returns negative number on error, otherwise t is set to the new thread. |
©2004 Bill Spitzak and others. See Main Page
for details.