🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.nativeapi
Article #10296

Re: Thread creation error: not enough memory

#10296
From: Remy Lebeau (TeamB)
Date: Thu, 22 Apr 2004 19:28
157 lines
5332 bytes
"Lothar" <Lothar.Huppertz@gmx.de> wrote in message
news:4087889d@newsgroups.borland.com...

> and how do I reexecute a thread which was used before?

By not allowing the thread to terminate in the first place, until you are
actually done using it completely.  Once the thread finishes what it is
doing, you can reuse it by simply suspending the thread when its operation
is done, and making sure Execute()'s main code can run multiple times.  Then
just store your thread instances into a list while they are running.  When
your application code needs to start a thread for an operation, go to the
list first to see if any suspended threads are waiting.  If so, just reset
the thread's variables and inner resources as needed and then Resume() the
thread.  If there are no threads waiting, then create a new thread instance
fresh.  For example (untested):

    class LockListHelper
    {
    private:
        TThreadList *FThreadList;
        TList *FList;
    public:
        LockListHelper(TThreadList *AList) : FThreadList(AList), FList(NULL)
        {
            if( FThreadList )
                FList = FThreadList->LockList();
        }
        ~LockListHelper()
        {
            Unlock();
        }
        Unlock()
        {
            if( FThreadList )
            {
                FThreadList->UnlockList();
                FThreadList = NULL;
                FList = NULL;
            }
        }
        operator bool () const {return (FList != NULL); }
        TList* operator ->() {return FList; }
    };


    TThreadList *Threads = NULL;

    __fastcall TForm1::TForm1(TComponent *Owner)
        : TForm(Owner)
    {
        Threads = new TThreadList;
    }

    __fastcall TForm1::~TForm1()
    {
        LockListHelper List(Threads);
        if( List )
        {
            for(int x = 0; x < List->Count; ++x)
            {
                TMyThread *Thread = (TMyThread*)(List->Items[x]);
                Thread->Terminate();
                Thread->Resume();
            }
            List.Unlock()

            while( LockListHelper(Threads)->Count > 0 )
                Sleep(100);
        }

        delete Threads;
        Threads = NULL;
    }

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
        TMyThread *Thread = NULL;

        LockListHelper List(Threads);
        if( List )
        {
            for(int x = 0; List->Count; ++x)
            {
                TMyThread *Temp = (TMyThread*)(List->Items[x]);
                if( (Temp->Suspended) && (!Temp->Terminated) )
                {
                    Thread = Temp;
                    break;
                }
            }
        }

        if( Thread == NULL )
            Thread = new TMyThread(Threads);

        Thread->Resume();
    }


    class TMyThread : public TThread
    {
    private:
        TThreadList *FList;
        void __Fastcall MyExecute();
    protected:
        void __fastcall Execute();
        void __fastcall DoTerminate();
    public:
        __fastcall TMyThread(TThreadList *AList);
        __property Terminated;
    };

    __fastcall TMyThread::TMyThread(TThreadList *AList)
        : TThread(true), FList(AList);
    {
        FreeOnTerminate = true;
        if( FList )
            FList->Add(this);
    }

    void __fastcall TMyThread::Execute()
    {
        while( !Terminated )
        {
            // reset any variables and resources here as needed...

            MyExecute();

            // perform any needed cleanup here...

            if( !Terminated )
                Suspend();
        }
    }

    void __fastcall TMyThread::MyExecute()
    {
        // your usual Execute() code goes here...
        // don't call Terminate() unless you really mean it!
    }

    void __fastcall TMyThread::DoTerminate()
    {
        try {
            TThread::DoTerminate();
        }
        __finally {
            if( FList )
                FList->Remove(this);
        }
    }

I'm sure there's more to it than that, but that is the basics to get you
started.


Gambit
Technical Details
Message-ID: <40881e5e@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!news.glorb.com!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail
References: <4086696d$1@newsgroups.borland.com> <40867831@newsgroups.borland.com> <408698f3@newsgroups.borland.com> <4086abc6$1@newsgroups.borland.com> <4086ed6a$1@newsgroups.borland.com> <4086fa2b$1@newsgroups.borland.com> <4087889d@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 10cc67,c8565ce6e82c46dd
X-Google-Attributes: gid10cc67,public
X-Google-ArrivalTime: 2004-04-22 12:40:01 PST
From: "Remy Lebeau \(TeamB\)" <gambit47.no.spam@no.spam.yahoo.com>
Newsgroups: borland.public.cppbuilder.nativeapi
References: <4086696d$1@newsgroups.borland.com> <40867831@newsgroups.borland.com> <408698f3@newsgroups.borland.com> <4086abc6$1@newsgroups.borland.com> <4086ed6a$1@newsgroups.borland.com> <4086fa2b$1@newsgroups.borland.com> <4087889d@newsgroups.borland.com>
Subject: Re: Thread creation error: not enough memory
Date: Thu, 22 Apr 2004 12:28:36 -0700
Lines: 159
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
NNTP-Posting-Host: 67.22.138.253
Message-ID: <40881e5e@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1082662494 67.22.138.253 (22 Apr 2004 12:34:54 -0700)
Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!news.glorb.com!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail