Recent

Author Topic: daemon and thread communication  (Read 6408 times)

cricketer

  • Newbie
  • Posts: 5
daemon and thread communication
« on: August 06, 2010, 03:28:55 am »
I've written a daemon that's working fine.
I want to create a number of threads that all need to have access to a central data structure, occasionally updated, but generally just read.

Since TDaemon is descended from TThread, I don't use synchronize (right?), but I still get an access violation when a thread tries to read a variable declared and initialised in the TDaemon object.

There is a I presume a way to do this, but I can't find it. Anyone know?

thanks

stephen

felipemdc

  • Administrator
  • Hero Member
  • *
  • Posts: 3538
Re: daemon and thread communication
« Reply #1 on: August 06, 2010, 08:06:41 am »
Synchronize the access with a critical section, something like:

uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  Classes, SyncObjs;

var
  MyVar  : Cardinal;
  MyVarCS: TCriticalSection;

procedure TMyThread.Execute;
begin
  MyVarCS.Enter;
  try
    MyVar := 5;
  finally
    MyVarCS.Leave;
  end;
end;

And somewhere in the initialization of the program put:
  MyVarCS := TCriticalSection.Create;

cricketer

  • Newbie
  • Posts: 5
Re: daemon and thread communication
« Reply #2 on: August 06, 2010, 03:53:57 pm »
hi

Thanks for that - it put me on to finding the solution, which I have!

The problem I was having was that whenever I accessed an element of the TDaemon object, I was getting an access violation. This happened whether I was within a critical section or not.

The problem was, of course, that the variables concerned were part of the TDaemon. The TDaemon is, I presume, just a thread in a loop, so any other access never completed, so the thing failed to complete.

The solution was to declare the variables outside the classes, just as members of the unit. It was obvious really, I was just being a bit blind!

so:

type
TTestThead1 = class(TThread)
  procedure Execute; override;
end;

TTestThead2 = class(TThread)
  procedure Execute; override;
end;


TTestDaemon = class(TDaemon)
private
......
public
...
end;

var
    MyGlobalDataThing  : string;


procedure TTestThread1.Execute;
   
begin
       MyGlobalDataThing := 'Some value';
end;

procedure TTestThread2.Execute;
   
begin
       MyGlobalDataThing := 'Some other value';
end;


function TTestDaemon.Start : boolean;
begin
       MyGlobalDataThing := 'Initial value';

       // Create and run both threads.........
end;

Of course the variable assignments shouldn't be done like that, but it's start of the correct solution!

 

TinyPortal © 2005-2018