如何从另一个线程获取指针?

时间:2008-10-16 14:47:45

标签: c++ multithreading

让我们有以下类定义:

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时(在主线程中)它崩溃了。我不知道如何获得指向内存的指针,在另一个线程中分配。这实际上是可能的吗?

3 个答案:

答案 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 :)