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

发布于 2024-11-27 15:10:41 字数 1531 浏览 2 评论 0 原文

我运行 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);
}

I run openCL /openGL program which uses wxWidget as gui enviroment

Inside object of class ,which derives from wxThread,I perform some complicated calculations and build many openCL programs.
I want to delete the thread .But the thread is not deleted immediately – it continue to build programs and just after it finishes with all the compilations.

I know that I can use wxThread::KIll() to exit the thread but it cause some memory problems so its not really an option.

I have myFrame class which is derived from wxFrame.it has pCanvas pointer ,which points to the object which is derived from wxCanvas
*pCanvas object includes the myThread (which runs the complicated calculation)

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);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一页 2024-12-04 15:10:41

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

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

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 标记为 易失性 可能不足以使更改会立即发生并且对其他线程可见,因此使用了屏障。

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

Killing a thread like that is indeed very bad. It's best to give the thread a chance to clean up.

Graceful thread termination is usually done by periodically checking a flag that tells it to exit:

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.
}

Depending on your CPU and compiler, simply marking continue_processing as volatile might not be enough to make the change happen immediately and visible to the other thread, so barriers are used.

You'll have to consult your compiler's documentation to see how to create a barrier... they're different in each one. VC++ uses _ReadWriteBarrier() and _WriteBarrier().

稍尽春風 2024-12-04 15:10:41

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

编辑:

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

If it is non joinable thread it will die itself and clean up

EDIT:

I found this link which I think will help a lot!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文