Wxwidgets——以正确的方式退出线程

wxwidgets - exit the thread the right way

本文关键字:方式 退出 线程 Wxwidgets      更新时间:2023-10-16

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

在类的对象中,我执行了一些复杂的计算,并构建了许多openCL程序,它派生自wxThread。我想删除这个线程,但是这个线程不会立即被删除——它会继续构建程序,直到它完成所有的编译。

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

我有myFrame类,它是从wxFrame派生的。它有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);
}

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

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

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()

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

编辑:

我发现了这个链接,我认为它会有很大帮助!