 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Preston Guest
|
Posted: Tue Jun 27, 2006 7:40 pm Post subject: How to write a Singleton thread |
|
|
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  |
|
| Back to top |
|
 |
Preston Guest
|
Posted: Tue Jun 27, 2006 8:36 pm Post subject: Re: How to write a Singleton thread |
|
|
| 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
|
Posted: Tue Jun 27, 2006 8:58 pm Post subject: Re: How to write a Singleton thread |
|
|
"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
|
Posted: Tue Jun 27, 2006 10:09 pm Post subject: Re: How to write a Singleton thread |
|
|
| 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
|
Posted: Tue Jun 27, 2006 10:14 pm Post subject: Re: How to write a Singleton thread |
|
|
| Quote: | type
TThreadedMethodQueue = class(TObject)
snip
function Pop: IMethod;
|
ouch ... breaking encapsulation badly ..  |
|
| Back to top |
|
 |
Martin James Guest
|
Posted: Tue Jun 27, 2006 10:43 pm Post subject: Re: How to write a Singleton thread |
|
|
| 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
|
Posted: Tue Jun 27, 2006 10:50 pm Post subject: Re: How to write a Singleton thread |
|
|
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 If the thread doesn't
have any interested parties, there's no sense in having it run. |
|
| Back to top |
|
 |
Peter Below (TeamB) Guest
|
Posted: Tue Jun 27, 2006 11:24 pm Post subject: Re: How to write a Singleton thread |
|
|
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
|
Posted: Tue Jun 27, 2006 11:29 pm Post subject: Re: How to write a Singleton thread |
|
|
| Quote: |
Yes, I could but it just doesn't feel right 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
|
Posted: Tue Jun 27, 2006 11:34 pm Post subject: Re: How to write a Singleton thread |
|
|
| 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
|
Posted: Tue Jun 27, 2006 11:36 pm Post subject: Re: How to write a Singleton thread |
|
|
| 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
|
Posted: Tue Jun 27, 2006 11:57 pm Post subject: IMethod |
|
|
Lee_Nover wrote:
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
|
Posted: Tue Jun 27, 2006 11:58 pm Post subject: Re: How to write a Singleton thread |
|
|
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
|
Posted: Wed Jun 28, 2006 12:11 am Post subject: Re: How to write a Singleton thread |
|
|
"Preston" wrote
| Quote: | ... I could but it just doesn't feel right 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
|
Posted: Wed Jun 28, 2006 12:22 am Post subject: Re: How to write a Singleton thread |
|
|
"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 |
|
 |
|
|
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
|
|