[DUG] graphics stops updating

Trevor Jones trevorj at ihug.co.nz
Mon Jun 20 16:25:44 NZST 2005


I reckon that a TCritical section to protect an integer variable from
multi-threaded access problems is WAY OVERKILL and will hurt the performance
of your app.

You can use the interlocked instructions to make multi-threaded operations
on integers completely threadsafe even on a multiple CPU machine.  AFAIK the
NT kernel itself uses these instructions to implement that magic that a
TCritical section uses, but if you're game you can use them raw, and avoid
all of the overhead.

If you have only one writer and multiple readers of the variable, then you
can use InterlockedExchange to set the new value.

More importantly, if you have a GUI reading an integer value that comes from
a thread, then it is probably easier to stop worrying about the thread-safe
nature of the whole thing, and switch to using the message queue that your
app already has.

  
Set up a message handler for a specific message in your form, and POST a
message with the integer value as the LParam of that message, then use the
LParam as the value to update the GUI controls.  Don't use WM_TIMER to do
this since the LParam of WM_TIMER does odd things (it's supposed to be a
pointer to a callback and so will jump into very strange parts of your
code).

Const 
  WM_AudioUpdate = WM_USER + 1;

Type
  TMyForm = class(TForm)

  Protected
    Procedure UpdateMeter(var Msg : TMessage); message WM_AudioUpdate;
  End;

Procedure TMyForm.UpdateMeter(var Msg : TMessage);
Begin
  If Msg.wParam = 0 then
    LeftMeter.value := Msg.lParam
  Else if Msg.wParam = 1 then
    RightMeter.value := Msg.lParam;
end



  
Then, in the event handler from your audio component you can use something
like:

  PostMessage(handle,WM_AudioUpdate,0.Sender.LeftValue);
  PostMessage(handle,WM_AudioUpdate,1,Sender.RightValue);

You can probably then just rely on the values coming through the message
queue and forget about all of that horrible thread stuff.

Trevor

  

-----Original Message-----
From: delphi-bounces at ns3.123.co.nz [mailto:delphi-bounces at ns3.123.co.nz] On
Behalf Of Allan, Samuel
Sent: Monday, 20 June 2005 11:18 a.m.
To: NZ Borland Developers Group - Delphi List
Subject: RE: [DUG] graphics stops updating

Plain old integer variables are not threadsafe.

However, if you have only one thread which writes to the variable, and
all others only read it, then you should be more or less safe. Even then
it is a bit dodgy.

To be safe you should protect access to your integer with
TCriticalSection or one of the other concurrency constructs. And if you
are gonna do that, then it would be best to encapsulate this within a
class to ensure that the concurrency construct chosen is always used
when accessing the variable. While I don't know what the stats object
is, I guess this is more or less what it does.





More information about the Delphi mailing list