Mein Problem ist, dass ich zwei TThread installiert habe (von Borland C++ VCL). Beide Konstruktoren sind erfolgreich. Aber nur der erste TThread wird ausgeführt.Zwei TThreads erfolgreich konstruiert, aber nur der erste wird ausgeführt
(Das Ziel dieses Codes ist das Laden von etwa 100 PNG-Bilddateien in eine Liste von Texturobjekten; diese Texturobjekte (TMyObject) haben eine "LoadFromFile" -Funktion, die etwa 60 Ticks dauert).
Ich habe viele Erläuterungen zu multithreading geblättert, und haben daher:
- versucht, die TMyThread zu konstruieren als suspendierte (: TThread (true)) und resume() für jede
- versucht aufgerufen Verwenden Sie TCriticalSection oder auch CRITICAL_SECTION, (zuerst als Mitglied von TMyThread ..., dann als Mitglied von TMainObject mit einem Zeiger auf jedes TMYThread ... und dann als globale Variable, die an der Seite von TMainObject und TMyThread)
- versucht, __thread in der Deklaration des Members hinzuzufügen von TMainObject zu jedem TMyThread
- geben versucht Applikations-> Process() in jedem TMyThread Konstruktor aufzuzurufen und Ausführen der Funktion
- versucht, einen „bool *“ jeden TMyThread weitergegeben verwendet die gemeinsamen Speicherzugriffe zu sperren und entsperren
- erfolglos versucht, einen std :: mutex
- versucht zu erklären Synchronisieren (NULL, NULL, 0,0) vor dem kritischen Speicherzugriffe zu fordern, um die Fäden an den Haupt-Thread während dieser Vorgänge
- versucht, wieder angebracht zu haben, Verwenden Sie zwei Paare von verschiedenen Listen für jeden Thread
- dieses interessante gefunden, aber brauchen Hilfe, um es zu implementieren: http://delphi.about.com/gi/o.htm?zi=1/XJ&zTi=1&sdn=delphi&cdn=compute&tm=41&f=00&tt=14&bt=0&bts=1&zu=http%3A//www.midnightbeach.com/jon/pubs/MsgWaits/MsgWaits.html
- auch diese: http://delphi.about.com/od/kbthread/a/threaded-delphi-tasks-thread-pool-otl-omnithreadlibrary-example.htm
- Lese über OTL und ASyncCalls hier: How Do I Choose Between the Various Ways to do Threading in Delphi?
=> kein Erfolg in all diesen Versuchen.
Hier unten ist mein Code, den ich versuchte zu vereinfachen. Jede Hilfe oder Erklärung würde helfen, meinen zweiten Thread auszuführen.
//---------------------------------------------------------------------------
class TMainClass
{
private:
TMyList<SmartPtr<TEvent> > mEventList;
SmartPtr<TMyThread> mThread1, mThread2;
int mCount;
protected:
int mCurrent, mLast;
TMyList<SmartPtr<TMyObject> > mObjectList;
TMyObject *mpObject;
void MyInit();
public:
TMainObject(TMyParentObject *parent);
virtual ~TMainObject();
virtual void PeriodicTask();
};
//---------------------------------------------------------------------------
class TMyThread : public TThread
{
TMyList<SmartPtr<TEvent> > *mpEventList;
TMyList<SmartPtr<TMyObject> > *mpObjectList;
int mStart, mEnd;
public:
TMyThread( TMyList<SmartPtr<TEvent> > *pEventList,
TMyList<SmartPtr<TMyObject> > *pObjectList,
int Start, int End);
virtual void __fastcall Execute(void);
};
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
TMainClass::TMainClass(TMyParentObject *parent)
{
mCount = 0;
}
TMainClass::~TMainClass()
{
if (mThread1.GetPtr() != NULL)
{
mThread1->Terminate();
mThread1 = SmartPtr<TMyThread> (NULL);
}
if (mThread2.GetPtr() != NULL)
{
mThread2->Terminate();
mThread2 = SmartPtr<TMyThread> (NULL);
}
mpObject = NULL;
mObjectList.Clear();
mEventList.Clear();
}
void TMainClass::MyInit()
{
if (mThread1.GetPtr() != NULL) return;
mObjectList.Clear();
mEventList.Clear();
mCount = GetNumberOfFiles("C:/MyPath/");
for (int i = 1; i <= mCount; i++)
{
SmartPtr<TEvent> lEvent (new TEvent(NULL, false, false, ""));
lEvent.GetPtr()->ResetEvent();
mEventList.Add(lEvent);
}
mThread1 = SmartPtr<TMyThread> (new TMyThread(&mEventList, &mObjectList, 1, floor(mCount/2.0))); // lock before that ?
mThread2 = SmartPtr<TMyThread> (new TMyThread(&mEventList, &mObjectList, floor(mCount/2.0)+1, mCount)); // lock before that ?
mCurrent = 0;
}
void TMainClass::PeriodicTask()
{
mpObject = NULL;
int lCount = mObjectList.Count();
if (lCount != 0)
{
++mCurrent;
mCurrent = min(mCurrent, lCount);
if ( mLast != mCurrent
&& mEventList[mCurrent]->WaitFor(120) != wrSignaled )
return;
mLast = mCurrent;
mpObject = mObjectList[mCurrent].GetPtr(); // lock before that ?
}
if (mpObject == NULL) return;
mpObject->MyObjectUtilisation(); // lock before that ?
}
//---------------------------------------------------------------------------
TMyThread::TMyThread( TMyList<SmartPtr<TEvent> > *pEventList, TMyList<SmartPtr<TMyObject> > *pObjectList,
int Start, int End);
:TThread(false)
{
mpEventList = pEventList; // lock before that ?
mpObjectList = pObjectList; // lock before that ?
mStart = Start;
mEnd = End;
FreeOnTerminate = false;
}
void __fastcall TMyThread::Execute(void)
{
for (int i = mStart; i <= mEnd; i++)
{
try
{
if (mpEventList != NULL && mpObjectList != NULL)
{
SmartPtr<TMyObject> pObject (new TMyObject());
pObject->LoadFromFile(i);
// common memory accesses before which I want to put a lock
mpObjectList->Insert(i,pObject);
mpEventList[i]->SetEvent();
// place where I could release this lock
}
}
catch(Exception &e)
{
ShowMessage("Exception in Execute : " + e.Message);
}
}
return;
}
Cheers, Arnaud.
Sind Sie sicher, beide Threads haben ihre 'Execute' Methode aufgerufen? Können Sie den Code in einem Debugger durchgehen, um zu sehen, was passiert? –
Kann jede Thread-Instanz auch korrekt ausgeführt werden, wenn Sie die Erstellung der anderen Instanz auskommentieren? Für Thread 2 haben 'mStart' und' mEnd' sinnvolle Werte? –
Nun, ich werde Ihre Texture-Objekte nicht neu entwickeln, also muss ich mit etwas anderem auskommen, das png-Dateien laden kann. TPngImage scheint eine gute Wette zu sein? –