私の問題は、2つのTThread(Borland C ++ VCLから)をインスタンス化したことです。両方のコンストラクターが成功します。ただし、最初のTThreadのみが実行されます。
(このコードの目的は、テクスチャオブジェクトのリストに約100個のpng画像ファイルをロードすることです。これらのテクスチャオブジェクト(TMyObject)には、約60ティック続く「LoadFromFile」関数があります)。
私はマルチスレッドに関する多くの説明を閲覧したので、次のようになりました。
- TMyThreadをSuspended(:TThread(true))として構築しようとし、それぞれに対してResume()を呼び出しました
- TCriticalSectionまたはCRITICAL_SECTIONを使用しようとしました(最初はTMyThread ...のメンバーとして、次に各TMYThread ...に渡されるポインターを持つTMainObjectのメンバーとして、次にTMainObjectの側で宣言されたグローバル変数として)およびTMyThread)
- 各TMyThreadに渡されるTMainObjectのメンバーの宣言に__threadを追加しようとしました
- 各TMyThreadコンストラクターとExecute関数でApplication->ProcessMessages()を呼び出そうとしました
- 各TMyThreadに渡された「bool*」を使用して、一般的なメモリアクセスをロックおよびロック解除しようとしました
- std::mutexの宣言に失敗しました
- これらの操作中にスレッドをメインスレッドに再接続するために、クリティカルメモリアクセスの前にSynchronize(NULL、NULL、0,0)を呼び出そうとしました
- スレッドごとに異なるリストの2つのペアを使用しようとしました
- これは面白いと思いましたが、実装するには助けが必要です: 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
- これも: http ://delphi.about.com/od/kbthread/a/threaded-delphi-tasks-thread-pool-otl-omnithreadlibrary-example.htm
- ここでOTLとASyncCallsについて読んでください: Delphiでスレッド化を行うためのさまざまな方法から選択するにはどうすればよいですか?
=>これらすべての試みで成功はありません。
以下は私が単純化しようとした私のコードです。ヘルプや説明があれば、2番目のスレッドを実行するのに役立ちます。
//---------------------------------------------------------------------------
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;
}
乾杯、アルノー。