Вызов QApplication::processEvents() внутри цикла OpenMP?

Приветствую всех,

В моем приложении QT я использую OpenMP для распараллеливания циклов. В цикле я хочу обновить значения индикатора выполнения текущего QMainWindow. Следующий фрагмент кода показывает, как я пытаюсь это сделать:

#ifdef OPENMP_ENABLE
#pragma omp parallel for
#endif

for (int i = 0; i < endIndex; i++) {
  getMainWindow()->setProgress(currProg); //change the value of QProgressBar
 QApplication::processEvents(); //update events,widgets

                  //Do some processing
 }

Здесь метод getMainWindow()->SetProgress() просто изменяет значения QProgressbar, прикрепленного к строке состояния QMainWindow.

При компиляции и запуске приложения с включенным OpenMP выдает следующую ошибку:

Ошибка ASSERT в QCoreApplication::sendEvent: "Невозможно отправить события объектам, принадлежащим другому потоку. Текущий поток 161975a0. Получатель "MainWindowClass" (типа "MainWindow") был создан в потоке 13d78f8", файл kernel\qcoreapplication.cpp, строка 348

Любые советы, как вызвать QApplication::processEvents() с OpenMP?

Заранее спасибо.


person Ashika Umanga Umagiliya    schedule 28.01.2011    source источник


Ответы (2)


Подкласс QThread и поместите туда свою бизнес-логику и используйте там OpenMP. Используйте сигналы и слоты для обновления QProgressBar.

Вы можете вызывать методы GUI только в основном потоке GUI. Когда вы вызываете QApplication::processEvents вне его, внутри потока OpenMP, вы нарушаете это правило.

person Vitor Py    schedule 28.01.2011

Я полагаю, что следующее также должно работать:

#pragma omp parrallel for
for (int i = 0; i < endIndex; i++) 
{
  #pragma omp single
  {
    getMainWindow()->setProgress(currProg); //change the value of QProgressBar
    QApplication::processEvents(); //update events,widgets
  }
  // Do some processing
}
person Mr. White    schedule 30.11.2012
comment
Попробовал это и получил: ошибка C3034: «одиночная» директива OpenMP не может быть непосредственно вложена в директиву «параллельно для» - person Julien M; 12.06.2014
comment
это может сделать if(omp_get_thread_num() ==0) вместо 'single' директивы. Хотя там не очень чисто. - person Mr. White; 06.04.2015