让我们有以下类定义:
CThread::CThread ()
{
this->hThread = NULL;
this->hThreadId = 0;
this->hMainThread = ::GetCurrentThread ();
this->hMainThreadId = ::GetCurrentThreadId ();
this->Timeout = 2000; //milliseconds
}
CThread::~CThread ()
{
//waiting for the thread to terminate
if (this->hThread) {
if (::WaitForSingleObject (this->hThread, this->Timeout) == WAIT_TIMEOUT)
::TerminateThread (this->hThread, 1);
::CloseHandle (this->hThread);
}
}
//*********************************************************
//working method
//*********************************************************
unsigned long CThread::Process (void* parameter)
{
//a mechanism for terminating thread should be implemented
//not allowing the method to be run from the main thread
if (::GetCurrentThreadId () == this->hMainThreadId)
return 0;
else {
m_pMyPointer = new MyClass(...);
// my class successfully works here in another thread
return 0;
}
}
//*********************************************************
//creates the thread
//*********************************************************
bool CThread::CreateThread ()
{
if (!this->IsCreated ()) {
param* this_param = new param;
this_param->pThread = this;
this->hThread = ::CreateThread (NULL, 0, (unsigned long (__stdcall *)(void *))this->runProcess, (void *)(this_param), 0, &this->hThreadId);
return this->hThread ? true : false;
}
return false;
}
//*********************************************************
//creates the thread
//*********************************************************
int CThread::runProcess (void* Param)
{
CThread* thread;
thread = (CThread*)((param*)Param)->pThread;
delete ((param*)Param);
return thread->Process (0);
}
MyClass* CThread::getMyPointer() {
return m_pMyPointer;
}
在主程序中,我们有以下内容:
void main(void) {
CThread thread;
thread.CreateThread();
MyClass* myPointer = thread.getMyPointer();
myPointer->someMethod(); // CRASH, BOOM, BANG!!!!
}
在使用myPointer时(在主线程中)它崩溃了。我不知道如何获得指向内存的指针,在另一个线程中分配。这实际上是可能的吗?
答案 0 :(得分:11)
所有线程都可以访问应用程序的内存空间。默认情况下,任何线程都可以看到任何变量,无论上下文如何(唯一的例外是变量声明为__delcspec(thread))
由于竞争条件,你正在崩溃。刚刚创建的线程在调用getMyPointer时尚未开始运行。您需要在新创建的线程和原始线程之间添加某种同步。换句话说,原始线程必须等到新线程发出信号表明它已经创建了对象。
答案 1 :(得分:0)
我试图了解你想要做的事情。对于像线程类这样的东西,它看起来过于复杂。你也介意发布类定义吗?
首先将process-argument的C样式转换移除到CreateThread():
this->hThread = ::CreateThread (NULL, 0,&runProcess, (void *)(this_param), 0, &this->hThreadId);
如果这不能编译你做错了什么! 从未投射函数指针!如果编译器抱怨你需要更改你的功能,不要试图抛弃错误!真!你只会让自己变得更糟!如果你再次这样做他们 *会来你家做...让我们看看你喜欢它!说真的,不要再这样做了。
顺便说一下,在Process()中,我认为做一些类似的事情会更合适:
assert(::GetCurrentThreadId() == hThreadId);
但是如果你声明它是私有的,它只能由你的CThread类访问,因此它应该不是问题。虽然断言很好!
*目前尚不清楚他们是谁,但很明显无论他们做什么都不会令人愉快!
答案 2 :(得分:-2)
Rob Walker指出 - 我真的很想念比赛状况。此外,崩溃不是在获取指针时,而是在使用它时。
简单的等待完成了这项工作:
MyClass* myPointer = thread.getMyPointer();
while (myPointer == 0)
{
::Sleep(1000);
}
myPointer->someMethod(); // Working :)