|
From: Jeroen v. d. Z. <je...@fo...> - 2005-11-23 14:30:21
|
On Wednesday 23 November 2005 07:33 am, Virginie Lefort wrote:
> Well, i have tried, and i cannot find how it works :-(
>
> So, in the run() function of my thread i do :
> while (_stop==0) {
> _info->change(); //_info is a pointer to a struct that contains the informations
> FXGUISignal signal(_win->getApp(),_win,FXSEL(SEL_COMMAND,MyWindow::ID_INFOUPDATE), _info);
> signal.signal();
> }
> }
No!!
Here's how it works:- you establish a FXGUISignal *in your main thread*, i.e. the thread
running the GUI. The FXGUISignal needs to persist throughout the program [or at least
as long as your program wants to run with multiple threads].
Do it like:
// Persistent variable, e.g. inside your MyMainWindow's constructor (lets say).
// After this call, a kernel object is added [using app->addInput()],
// for the gui-thread to watch. When it becomes signalled, the gui-thread
// dispatches to a handler
guisignal=new FXGUISignal(getApp(),this,ID_INFOUPDATE);
Then you write a callback handler for the message SEL_IO_READ, ID_INFOUPDATE
FXMAPFUNC(SEL_IO_READ,MyMainWindow::ID_INFOUPDATE,MyMainWindow::onSgnlInfoUpdate),
You write the handler code for onSgnlInfoUpdate(). What it does depends on your application;
its possible it does nothing at all, in which case the notification from the thread has no
effect other than to wake up the main gui-thread so as to cause it to run through its GUI-
update process and refresh all the widgets.
Your thread calls:
guisignal->signal();
This will "kick" the gui thread from its slumber.
What actually happens:
1) when you create a FXGUISignal, a unix pipe is created and the reading end of it is
added to FXApp's addInput() routine. This causes the event loop to watch the pipe
for activity.
2) The call to signal from the worker thread simply writes a byte into the pipe, if there's
nothing in the pipe yet. This makes the pipe filedescriptor which the FXApp is watching
become "signalled".
3) The system call select() which is used to watch all sockets and pipes in FXApp falls through,
and after figuring out which file descriptor was the signalled one, FXApp dispatches to
FXGUISignal::onSignal. This routine drains the pipe [thereby making it unsignalled again!]
and then turns around and calls your onSgnlInfoUpdate callback handler.
As you write multi-threaded code, note that GUI and worker thread may run at THE SAME TIME and
thus care must be exercised with critical sections and so on. FXApp provides one "blanket"
mutex, which is essentially a critical section around any callback exercised by the main
thread. This is the FXApp's global mutex.
In realistic multi-threaded applications you're likely to have many more fine-grained critical
sections.
Hope this explains,
- Jeroen
|