wxwidgets - правильно выйти из потока - PullRequest
0 голосов
/ 02 августа 2011

Я запускаю программу openCL / openGL, которая использует wxWidget в качестве среды графического интерфейса

Внутри объекта класса, производного от wxThread, я выполняю некоторые сложные вычисления и собираю много программ openCL.Я хочу удалить поток. Но поток не удаляется сразу - он продолжает собирать программы и сразу после того, как завершает со всеми компиляциями.

Я знаю, что могу использовать wxThread::KIll() для выхода из потока, ноэто вызывает некоторые проблемы с памятью, поэтому на самом деле это не вариант.

У меня есть класс myFrame, производный от wxFrame.it, имеет указатель 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 ]

1 голос
/ 02 августа 2011

Если это не присоединяемая нить, она умрет сама и очистит

EDIT:

Я нашел эту ссылку , которая, я думаю, очень поможет!

1 голос
/ 02 августа 2011

Убить такую ​​нить действительно очень плохо.Лучше всего дать потоку возможность очиститься.

Изящное завершение потока обычно выполняется путем периодической проверки флага, указывающего на выход:

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

В зависимости от вашего процессора и компиляторапростого пометки continue_processing как volatile может быть недостаточно, чтобы изменение произошло немедленно и стало видимым для другого потока, поэтому используются барьеры.

Вам придется обратиться к документации вашего компилятора, чтобы увидеть, каксоздать барьер ... они разные в каждом.VC ++ использует _ReadWriteBarrier() и _WriteBarrier().

...