c++11 スレッド API に似たスタイルで、win32 スレッドと pthreads のラッパー クラスを作成しています。私の問題は、実際のスレッドが終了したときにスレッド オブジェクト インスタンスを更新することに関するものです。以下は私が持っている解決策ですが、安全かどうかはわかりません。
/* Thread wrapper class */
class Thread
{
public:
enum ThreadState
{
DETACHED = 0,
RUNNING
};
Thread();
Thread(void* (*start) (void*), void* arg);
~Thread();
Thread& operator=(Thread& other);
void Join();
int32_t SetPriority(int32_t priority);
void Detach();
ThreadHandle GetNativeHandle();
ThreadState GetThreadState();
private:
ThreadHandle mHandle;
ThreadState mState;
void* (*mFunctionPointer) (void*);
void* mArg;
static void* Run(void* arg);
ThreadHandle _CreateThread(void* (*start) (void*), void* arg);
void _JoinThread(ThreadHandle& handle);
};
2 番目のコンストラクターは、スレッドを開始します。実装は次のとおりです。
Thread::Thread(void* (*start) (void*), void* arg)
{
mFunctionPointer = start;
mArg = arg;
mState = Thread::RUNNING;
mHandle = _CreateThread(&Run, (void*)this);
if (!mHandle)
mState = Thread::DETACHED;
}
Run メソッドを実行し、このオブジェクト インスタンスへのポインターを渡すスレッドを作成します。その理由は、スレッドが関数を実行すると、状態を DETACHED に設定して、完了したことを知らせるためです。
これが実行方法です
void* Thread::Run(void* arg)
{
Thread* thread = static_cast<Thread*>(arg);
if (thread && thread->mFunctionPointer && thread->mArg && thread->mState == Thread::RUNNING)
thread->mFunctionPointer(thread->mArg);
if (thread && thread->mFunctionPointer && thread->mArg && thread->mState == Thread::RUNNING)
thread->Detach();
return NULL;
}
また、これはスレッド デストラクタでも呼び出される Detach() です。
void Thread::Detach()
{
mState = Thread::DETACHED;
mHandle = NULL;
mArg = NULL;
mFunctionPointer = NULL;
}
これはまったく安全ではないと感じています。たとえば、Thread オブジェクトがスタック上に構築され、そのスレッドの実行中にスコープ外になった場合です。Thread オブジェクトのデストラクタはその状態とデータ メンバーを NULL にしますが、メモリの場所は上書きされる可能性がありますか?
これを解決する良い方法はありますか?
ありがとう