代码之家  ›  专栏  ›  技术社区  ›  m_pGladiator

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

  •  3
  • m_pGladiator  · 技术社区  · 17 年前

    让我们有以下类定义:

    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 回复  |  直到 17 年前
        1
  •  11
  •   Rob Walker    17 年前

    所有线程都可以访问应用程序的内存空间。默认情况下,无论上下文如何,任何线程都可以看到任何变量(唯一的例外情况是声明为udelcspec(thread)的变量)

    你因比赛情况而撞车。您刚才创建的线程在您调用getmypointer时尚未开始运行。您需要在新创建的线程和原始线程之间添加某种同步。换句话说,源线程必须等待,直到新线程向它发出创建对象的信号。

        2
  •  0
  •   Andreas Magnusson    17 年前

    我在想你想做的事情。对于线程类来说,它看起来过于复杂。你也可以把课程定义贴出来吗?

    首先删除createThread()的进程参数的C样式转换:

    this->hThread = ::CreateThread (NULL, 0,&runProcess, (void *)(this_param), 0, &this->hThreadId);
    

    如果这不编译,你就做错了! 从来没有 调用函数指针!如果编译器抱怨您需要更改您的函数,不要试图消除错误!真的?你只会让自己更糟!如果你再这样做 他们 *会来你家做…让我们看看你是怎么想的!说真的,别再这样了。

    顺便说一句,在process()中,我认为更适合这样做:

    assert(::GetCurrentThreadId() == hThreadId);
    

    但是,如果您声明它是私有的,那么它应该只能由CThread类访问,因此它不应该是问题。但是断言是好的!

    *不清楚是谁 他们 但是很明显 他们 这样做不会让人愉快!

        3
  •  -2
  •   m_pGladiator    17 年前

    正如罗布·沃克指出的那样——我真的错过了比赛条件。另外,当获取指针时,崩溃不是,而是在使用指针时。

    一个简单的等待完成了任务:

    MyClass* myPointer = thread.getMyPointer(); 
    
    while (myPointer == 0) 
    {
        ::Sleep(1000);
    }
    
    myPointer->someMethod(); // Working :)