2016-04-08 3 views
0

Я разрабатываю большой инструмент оптимизации с использованием Qt. Для лучшего использования процессора я использую QThreads. Затем я перемещаю объекты-работники (полученные из QObject, содержащие члены данных вне QObject) в потоки. Все выглядит отлично, строит отлично и работает плавно в Linux с использованием GCC и Qt 4.8QThreads с использованием MinGw не работает должным образом под окнами

Однако, используя MinGw, используя Qt 5.5 под Windows, расчет занял гораздо больше времени. Похоже, что потоки блокируются где-то в расчете и сериализуются. Я отобрал некоторые отладочные сообщения, чтобы убедиться, что потоки работают правильно. Похоже, что есть бутылочка, которая существует в Windows, но не под Linux. Я не думаю, что версия Qt имеет значение, я бы предпочел, чтобы проблема была вызвана MinGw. ОС - это Windows 7 и Debian. Я использую скомпилированные бинарные файлы MinGw Qt5.

Есть ли дополнительная конфигурация для сборки Qt MinGw? Или есть проблема с использованием элементов non QObject при перемещении рабочих объектов в потоки? Может ли это быть проблемой с разными типами потоков, QThread использует внутренне? Заранее спасибо :-)

EDIT:

Отправной О.Б. темы выглядит следующим образом.

for (int i = 0; i < this->numberOfCores; i++) 
    { 
     QThread *thread = new QThread(this); 
     thread->setObjectName("Thread " + QString::number(i)); 
     Calculator *calculator = new Calculator(/* Skip parameters */); 

     calculator->moveToThread(thread); 
     connect(calculator, SIGNAL(debugInfo(DebugData)), this, SIGNAL(debugInfo(DebugData))); 
     connect(this, SIGNAL(startCalculator()), 
       calculator, SLOT(startCalculation())); 
     connect(calculator, SIGNAL(solutionFound(Solution*)), 
       this, SLOT(addSolution(Solution*))); 
     connect(calculator, SIGNAL(calculationFinished()), this, SLOT(calculatorFinished())); 

     thread->start(QThread::HighestPriority); 

Я использовал этот подход несколько раз, и он всегда работал.

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

+0

Возможно, проблема связана с вашим кодом, который не отображается. – dtech

+0

Вы работаете на одной машине, только в другой ОС? – thuga

+0

@thuga Та же физическая машина просто виртуальная машина с Debian – Liachtei

ответ

1

При каждом излучении сигнала потоки с высоким приоритетом будут синхронизироваться с потоком с более низким приоритетом, который принимает вызовы слотов с поперечным потоком. Вероятно, это источник различий в платформе: разные ядра обращаются к временному приоритету, и, кроме того, на Linux циклы событий от glib, а в Windows это не так. Они будут вести себя по-разному, когда речь заходит о синхронизации по потокам с разными приоритетами. Если принимающий поток проводит много времени в цикле событий, активно рассылает события, он может нанести ущерб потокам с высоким приоритетом.

Возможно, контр-интуитивно, решение может быть таким же простым, как , а не, что делает потоки вычислений приоритетными.

В любом случае, ваши пользователи будут ненавидеть вас за то, что лишили их интерактивной производительности для некоторых расчетов, которые должны выполняться в фоновом режиме. Потоки вычислений будут пресекать потоки графического интерфейса по умолчанию, система будет чувствовать себя очень медлительной для интерактивного пользователя, и это относится и к вашему собственному пользовательскому интерфейсу! При этом потоки вычислений должны быть ниже ниже. Это, конечно, предполагает, что вычисления не используются для управления взаимодействием (например, физический движок в игре); если они это сделают, и вы считаете, что приложение заслуживает этого, вы должны повысить приоритет всего процесса.

0

Как вы начинаете тему?

#include <QObject> 
#include <QThread> 
class _Object : public QObject 
{ 
     Q_OBJECT 
public: 
    explicit _Object(QObject *parent = 0); 
    void _setup(QThread &th); 

public slots: 
    void do_stuff_you_want(); 
}; 

и _Object.cpp:

#include "_object.h" 

_Object::_Object(QObject *parent) : 
QObject(parent) 
{ 
} 

void _Object::_setup(QThread &thread) 
{ 
    connect(&thread,SIGNAL(started()),this,SLOT(do_stuff_you_want())); 
} 

void _Object::do_stuff_you_want(){......} 

В main.cpp:

#include <all_u_need> 
#include <QThread> 
#include "_object.h" 

int main(.. .. ..) 
{ 
    ... 

    QThread thread_obj_runns_in; 
    _Object object_to_run; 

    object_to_run._setup(); 
    object_to_run.moveToThread(&thread_obj_runns_in); 

    thread_obj_runns_in.start(); 

    ... 
    return app.exec(); 
} 

Я получил много проблем в использовании run() и QThread подклассов. Поскольку я начал использовать его вот так, у меня больше не было проблем с потоками.

Что я хочу сказать: создать объект QObject и переместить его в поток и не подклассы QThread.

Надеюсь, я мог бы вам помочь.

+0

Я не подклассифицировал QThread. См. Редактирование. Но спасибо вам все равно – Liachtei

+0

да я еще не видел ваш код :) –

Смежные вопросы