wxwidgets - 以正确的方式退出线程

时间:2011-08-02 12:43:23

标签: c++ multithreading visual-studio-2010 wxwidgets

我运行openCL / openGL程序,它使用wxWidget作为gui环境

类的内部对象,它派生自wxThread,我执行一些复杂的计算并构建许多openCL程序。 我想删除该线程。但是线程不会立即被删除 - 它继续构建程序,并在完成所有编译之后。

我知道我可以使用wxThread::KIll()退出线程,但它会导致一些内存问题,所以它实际上不是一个选项。

我有一个派生自wxFrame的myFrame类。它有pCanvas指针,它指向从wxCanvas派生的对象 * pCanvas对象包含myThread(运行复杂的计算)

void myFrame::onExit(wxCommandEvent& WXUNUSED(event))
{
       if(_pCanvas != NULL )
       {
              wxCriticalSectionLocker enter(_smokeThreadCS);
              // smoke thread still exists
              if (_pCanvas->getThread() != NULL)
              {
                     //_pCanvas->getSmokeThread()->Delete(); <-waits until thread ends and after it application terminates
                     _pCanvas->getSmokeThread()->Kill();     <- immediately makes the application not responding
              }
       }
       // exit from the critical section to give the thread
       // the possibility to enter its destructor
       // (which is guarded with m_pThreadCS critical section!)

       while (true)
       {
              { // was the ~MyThread() function executed?
                     wxCriticalSectionLocker enter(_smokeThreadCS);
                     if (!_pCanvas->getSmokeThread()) break;
              }

              // wait for thread completion
              wxThread::This()->Sleep(1);
       }
       DestroyChildren();
       Destroy();
       // Close the main frame, this ends the application run:
       Close(true);
}

2 个答案:

答案 0 :(得分:1)

杀死这样的线程确实非常糟糕。最好给线程一个清理的机会。

优雅的线程终止通常通过定期检查告诉它退出的标志来完成:

volatile bool continue_processing = true;
thread thread;

void compile_thread()
{
    while(continue_processing)
    {
        // compile one OpenCL program.
    }
}

void terminate()
{
    read_write_barrier();
    continue_processing = false;
    write_barrier();

    thread.join(); // wait for thread to exit itself.
}

根据您的CPU和编译器,仅将continue_processing标记为volatile可能不足以使更改立即发生并且对另一个线程可见,因此使用障碍。

您必须查阅编译器的文档,了解如何创建障碍......它们各自不同。 VC ++使用_ReadWriteBarrier()_WriteBarrier()

答案 1 :(得分:1)

如果它是不可连接的线程,它将自行消亡并清理

修改

我发现this link我认为会有很多帮助!