BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

How to write a Singleton thread
Goto page 1, 2  Next
 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi OO design
View previous topic :: View next topic  
Author Message
Preston
Guest





PostPosted: Tue Jun 27, 2006 7:40 pm    Post subject: How to write a Singleton thread Reply with quote



I want to write a Singleton that is a TThread. The problem I'm having is
with the newInstance and freeInstance methods which you would normally
override for a singleton class. Specificallly, the TThread class does
some critital stuff in the constructor and destructor before newInstance
and freeInstance are called.

I'm using the example given at
http://community.borland.com/article/0,1410,22576,00.html

Any help is appreciated Smile
Back to top
Preston
Guest





PostPosted: Tue Jun 27, 2006 8:36 pm    Post subject: Re: How to write a Singleton thread Reply with quote



Quote:
What scope do you want for your singleton?

Why or for what purpose?

--JohnH

(By the way, singleton as used here is a not
very descriptive.)

For the scope I just want it to be a class that I can instantiate
anywhere in my project. If the class has already been instantiated then
it would return the existing instance.

As for the purpose, I have a background thread that checks for the
presence of web orders. When orders are found, the class runs through a
list of registered listeners (this is just a TList with a bunch of
TMethod pointers) and calls them so they do can do whatever.

I've written singletons before using this example, but the TThread stuff
is making the problem more difficult.

I've seen other examples that rely on the users of the class to
reference .Instance and .FreeInstance rather than using reference
counting. I'd like to avoid that as it requires the users of the class
to be aware of each other.

Preston
Back to top
John Herbster
Guest





PostPosted: Tue Jun 27, 2006 8:58 pm    Post subject: Re: How to write a Singleton thread Reply with quote



"Preston" <na (AT) na (DOT) com> wrote
Quote:
I want to write a Singleton that is a TThread.

Preston,

What scope do you want for your singleton?

Why or for what purpose?

--JohnH

(By the way, singleton as used here is a not
very descriptive.)
Back to top
Lee_Nover
Guest





PostPosted: Tue Jun 27, 2006 10:09 pm    Post subject: Re: How to write a Singleton thread Reply with quote

Quote:
As for the purpose, I have a background thread that checks for the
presence of web orders. When orders are found, the class runs through a
list of registered listeners (this is just a TList with a bunch of
TMethod pointers) and calls them so they do can do whatever.

I've done something similar
it's a simple class that creates a thread with a queue of methods
http://leenover.homeip.net/isapi/pas2html.dll/pas2html?File=/delphi/ThreadedQ/
or
http://tinyurl.com/ftxmf

usage example:

FTMQ := TThreadedMethodQueue.Create;
FTMQ.Push(TStockReader.Create(LIDList, FDate, Handle));

that Handle is the Form's handle and is for receiving method progress(completion) events
it could alternatively wait for new items .. but why :)


unit MethodIntf;

interface

type
IMethod = interface(IUnknown)
['{34499011-CC49-46EF-95CC-6434FDD58700}']
procedure Execute;
end;

implementation

end.





unit ThreadedQueue;

interface

uses Classes, Contnrs, SyncObjs, SysUtils, MethodIntf;

type
TThreadedMethodQueue = class(TObject)
protected
FList: IInterfaceList;
FThread: TThread;
procedure CheckThread;
procedure ThreadTerminated(Sender: TObject);
public
destructor Destroy; override;
procedure Clear;
function Pop: IMethod;
procedure Push(AMethod: IMethod);
procedure Remove(AMethod: IMethod);
end;

TQueueThread = class(TThread)
protected
FQueue: TThreadedMethodQueue;
procedure Execute; override;
public
constructor Create(Queue: TThreadedMethodQueue); reintroduce;
end;

implementation

destructor TThreadedMethodQueue.Destroy;
begin
FreeAndNil(FThread);
inherited;
end;

procedure TThreadedMethodQueue.CheckThread;
begin
if FThread = nil then
FThread:=TQueueThread.Create(Self);
FThread.OnTerminate:=ThreadTerminated;
FThread.FreeOnTerminate:=true;
FThread.Resume;
end;

procedure TThreadedMethodQueue.Clear;
begin
if FList = nil then
exit;

FList.Clear;
FList:=nil;
end;

function TThreadedMethodQueue.Pop: IMethod;
var
LCount: Integer;
begin
if FList = nil then
Result := nil
else
begin
LCount := FList.Count;
if LCount = 0 then
begin
Result:=nil;
FList:=nil;
end
else
begin
Result := FList[LCount-1] as IMethod;
FList.Delete(LCount-1);
// count was 1 before we removed the last item
if LCount = 1 then
FList:=nil;
end;
end;
end;

procedure TThreadedMethodQueue.Push(AMethod: IMethod);
begin
if FList = nil then
FList:=TInterfaceList.Create;
FList.Insert(0, AMethod);
CheckThread;
end;

procedure TThreadedMethodQueue.Remove(AMethod: IMethod);
begin
if Assigned(FList) then
begin
FList.Remove(AMethod);
if FList.Count = 0 then
FList:=nil;
end;
end;

procedure TThreadedMethodQueue.ThreadTerminated(Sender: TObject);
begin
FThread:=nil;
end;

constructor TQueueThread.Create(Queue: TThreadedMethodQueue);
begin
inherited Create(true);
FQueue:=Queue;
end;

procedure TQueueThread.Execute;
var
LMethod: IMethod;
begin
LMethod:=FQueue.Pop;
while (not Terminated) and Assigned(LMethod) do
begin
LMethod.Execute;
LMethod:=FQueue.Pop;
end;
end;

end.
Back to top
Lee_Nover
Guest





PostPosted: Tue Jun 27, 2006 10:14 pm    Post subject: Re: How to write a Singleton thread Reply with quote

Quote:
type
TThreadedMethodQueue = class(TObject)
snip
function Pop: IMethod;


ouch ... breaking encapsulation badly .. Smile
Back to top
Martin James
Guest





PostPosted: Tue Jun 27, 2006 10:43 pm    Post subject: Re: How to write a Singleton thread Reply with quote

Quote:

As for the purpose, I have a background thread that checks for the
presence of web orders. When orders are found, the class runs through a
list of registered listeners (this is just a TList with a bunch of
TMethod pointers) and calls them so they do can do whatever.

I've written singletons before using this example, but the TThread stuff
is making the problem more difficult.


Can you just dodge the issue entirely and simply create one instance at app
startup, perhaps in an initialization section, and just keep it for the life
of the app?

Rgds,
Martin
Back to top
Preston
Guest





PostPosted: Tue Jun 27, 2006 10:50 pm    Post subject: Re: How to write a Singleton thread Reply with quote

Martin James wrote:

Quote:
Can you just dodge the issue entirely and simply create one instance at app
startup, perhaps in an initialization section, and just keep it for the life
of the app?

Rgds,
Martin


Yes, I could but it just doesn't feel right Wink If the thread doesn't
have any interested parties, there's no sense in having it run.
Back to top
Peter Below (TeamB)
Guest





PostPosted: Tue Jun 27, 2006 11:24 pm    Post subject: Re: How to write a Singleton thread Reply with quote

Preston wrote:

Quote:
I want to write a Singleton that is a TThread. The problem I'm having
is with the newInstance and freeInstance methods which you would
normally override for a singleton class. Specificallly, the TThread
class does some critital stuff in the constructor and destructor
before newInstance and freeInstance are called.

Well, do not make the thread a singleton, create a helper class that
internally creates a thread and make that helper class the singleton.




--
Peter Below (TeamB)
Don't be a vampire (http://slash7.com/pages/vampires),
use the newsgroup archives :
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be
Back to top
Martin James
Guest





PostPosted: Tue Jun 27, 2006 11:29 pm    Post subject: Re: How to write a Singleton thread Reply with quote

Quote:

Yes, I could but it just doesn't feel right Wink If the thread doesn't
have any interested parties, there's no sense in having it run.

Well, surely it will have some interested parties at some time during your
app run. By postponing the create until the first interested party needs to
added to the list, you are saving on a bit of memory, (for a stack etc), for
a portion of your app run at the expence of added complexity in managing the
thread. This is not usually worth the candle with thread objects that are
so awkward compared with most objects, having their own OS-provided
execution and handle etc. For instance, this is not thread-safe:

-------------------------------
if (someThread = nil) then
someThread :=TsomeThread.Create;

-------------------------------

Two, (or more), threads might perform the check and both get 'true' as a
result so creating two instances of TsomeThread.

unless the code is wrapped in a CS, and then there is the problem of
creating only one CS <g>

I have never it much thought, really, but a classic' thread singleton sounds
like a bad idea, IMHO. I am prepared to be convinced otherwise, however - I
have never attempted it and so have no experience.

Rgds,
Martin
Back to top
Martin James
Guest





PostPosted: Tue Jun 27, 2006 11:34 pm    Post subject: Re: How to write a Singleton thread Reply with quote

Quote:
I don't know anything about touchy feely stuff,

<g>

Quote:
but if you only want zero or one instantiation
for your project, then why not have just one
global variable to hold either nil or a pointer
to the thread, if it exists. If this var is nil when
you need the thread, then instantiate the thread
and save the pointer to it.

Not safe, in general. Two or more other threads might call 'create' at the
same time, both get back nil as the gobal variable and create two or more
'singleton' threads, all but one of which will get leaked.

Rgds,
Martin
Back to top
Lee_Nover
Guest





PostPosted: Tue Jun 27, 2006 11:36 pm    Post subject: Re: How to write a Singleton thread Reply with quote

Quote:
Not safe, in general.

that's why it would be implemented as a function, like:

function MyThread: TMyThread;
begin
EnterLock;
try
if GMyThread = nil then
CreateTheThread;
Result := GMyThread;
finally
LeaveLock;
end;
end;
Back to top
Preston
Guest





PostPosted: Tue Jun 27, 2006 11:57 pm    Post subject: IMethod Reply with quote

Lee_Nover wrote:
Quote:
I've done something similar
it's a simple class that creates a thread with a queue of methods
http://leenover.homeip.net/isapi/pas2html.dll/pas2html?File=/delphi/ThreadedQ/


Hi Lee,
While your example doesn't show a singleton thread I did find the method
queuing interesting.

I really don't understand interfaces too much so I've got some questions
about your implementation. How does a IMethod a TMethod which is a pair
of pointers?

Preston
Back to top
Preston
Guest





PostPosted: Tue Jun 27, 2006 11:58 pm    Post subject: Re: How to write a Singleton thread Reply with quote

Peter Below (TeamB) wrote:
Quote:
Well, do not make the thread a singleton, create a helper class that
internally creates a thread and make that helper class the singleton.


Are you saying that it can't be done or is generally bad for some reason?
Back to top
John Herbster
Guest





PostPosted: Wed Jun 28, 2006 12:11 am    Post subject: Re: How to write a Singleton thread Reply with quote

"Preston" wrote
Quote:
... I could but it just doesn't feel right Wink If the thread
doesn't have any interested parties, there's no sense
in having it run.

I don't know anything about touchy feely stuff,
but if you only want zero or one instantiation
for your project, then why not have just one
global variable to hold either nil or a pointer
to the thread, if it exists. If this var is nil when
you need the thread, then instantiate the thread
and save the pointer to it.

On project destroy, then free the thread if its
pointer is not nil.

JohnH
Back to top
Martin James
Guest





PostPosted: Wed Jun 28, 2006 12:22 am    Post subject: Re: How to write a Singleton thread Reply with quote

"Lee_Nover" <Lee_Nover[nospam]@delphi-si.com> wrote in message
news:op.tbthy4sxignj8p@stupidirko...
Quote:
Not safe, in general.

that's why it would be implemented as a function, like:

function MyThread: TMyThread;
begin
EnterLock;
try
if GMyThread = nil then
CreateTheThread;
Result := GMyThread;
finally
LeaveLock;
end;
end;

OK, where would you create the lock synchro-object? <g>

Rgds,
Martin
Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi OO design All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.