我正在围绕 win32 线程和 pthreads 做一个包装类,其风格类似于 c++11 线程 api。我的问题是关于在实际线程退出时更新线程对象实例。以下是我的解决方案,但我不确定它是否安全。
/* 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);
};
第二个构造函数启动一个线程。这是实现:
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,但内存位置可能会被覆盖,不是吗?
有什么好的方法可以解决这个问题吗?
谢谢