2012-06-25 7 views
0

я попытаюсь объяснить, что моя программа используется, чтобы сделать и то, что я Тринг изменить:QThread передачи данных и из

Я имел эту функцию, которая выбежала на кнопку мыши из главного потока в классе MainWindow : общественный QMainWindow:

функция выглядит, как это и указано в другом файле:

void MakeMeshStructure(MeshStructureLayers layers, 
         Handle_AIS_InteractiveContext theContext, 
         Handle_TDocStd_Document aDoc, 
         MyMesh &mesh, 
         int detail_vertex, 
         double insulation_thickness, 
         OpenMesh::VPropHandleT<MyMesh::Scalar> _max_beam_offset); 
} 

Что это делает: он работает на сетке и создает геометрию для каждой вершины, грани и края сетки. Эта геометрия отображается с помощью контекстного меню. Этот процесс занимает очень много времени (30 минут) и блокирует gui.

Что бы я хотел сделать, так это столько потоков, сколько QThread :: idealThreadCount() и освобождать gui при его вычислении и ускорении. (Правильно ли это?)

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

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

http://pastebin.com/u/mzagar

Проблема получает все данные вокруг в правильном направлении, и получать потоки работать. Где я должен использовать мьютексы. На всех данных, которые могут быть записаны во время работы потока с помощью mainthread? Очень смущенный. ти

редактировать:

Я отредактировал мой код: http://pastebin.com/u/mzagar Я сделал STRUCT cadData передать данные вокруг. Это, как я начинаю темы:

connect(this, SIGNAL(startMake1(cadData)), cThreads.at(0), SLOT(MakeMesh(cadData))); 
//... 
cThreads.at(0)->moveToThread(threads.at(0)); 
//... 
threads.at(0)->start(); 
//... 
emit startMake1(aCadDatas.at(0)); 
//... 

Проблема заключается в нити не кажется, работают одновременно, а также графический интерфейс замерзает. Процесс идет в так:

  • GUI зависает
  • вещей в потоке 1 сделано
  • вещей в потоке 1 сделаны снова
  • вещей в потоке 2 сделаны
  • вещей в нити 2 получить сделать еще раз
  • ...
  • GUI размораживает

Любые идеи, почему?

edit2:

Я снял несколько пробегов в том же потоке, перемещая это конструктор класса:

connect(this, SIGNAL(startMake1(cadData)), cThreads.at(0), SLOT(MakeMesh(cadData))); 
//... 
cThreads.at(0)->moveToThread(threads.at(0)); 
//... 
threads.at(0)->start(); 
+0

Вам нужно будет выяснить, что вы замерзаете самостоятельно, используя отладчик или профилировщик, или путем разгона вызовов на printf() или qDebug или т. Д., Чтобы увидеть, где приостановлено выполнение в потоке графического интерфейса. Вы также можете поместить некоторые вызовы printf («% i \ n», (int) pthread_self()) как в коде GUI, так и в коде mesh-worker, чтобы убедиться, что код сети действительно работает в отдельном потоке, как ожидалось , –

ответ

2

Поскольку вы используете QThread, вероятно, можно избежать явного использования мьютексы и например, используя механизм Qt, защищенный потоками и сигналами, для выполнения вашей работы.В основном вы должны упаковать данные, которые нужно отправить потоку в объект, а затем испустить сигнал, который имеет этот объект в качестве аргумента. Поток получит копию этого объекта в слоте (который вы ранее подключили к вашему сигналу) и затем начните использовать данные. Чтобы вернуть данные из рабочего потока в основной поток, вы сделаете то же самое снова в обратном порядке. Here's статья с некоторым примером кода.

+0

Будет ли этот пакет работать, если он содержит ссылку на сетку и Handle_AIS_InteractiveContext? Это все еще в порядке, когда несколько потоков меняют InteractiveContext? Любые примеры этого объекта? – pazduha

+0

Это будет зависеть от того, как реализован сетчатый код. Обычно это нормально, если только один поток имеет доступ (чтение или запись) к объекту в любой момент времени. –

+0

Также помните следующее важное сообщение о QThreads: http: //labs.qt.nokia.com/2010/06/17/youre-doing-it-wrong/ – Martin

0

Чтобы добавить к ответу Джереми: вы можете сделать то же самое, отправив события между QObjects вместо использования механизма сигнального слота. Используйте то, что наиболее удобно для вас.

Ключом является использование встроенного мьютекса цикла событий Qt. Когда вы отправляете сигналы на объекты, живущие в потоке, отличном от отправителя, сигнал преобразуется в QMetaCallEvent и отправляется в очередь событий получающего QObject. Разумеется, это делается в потокобезопасном режиме, и все, что нужно сделать, - это использовать его. Отправка явных событий работает одинаково. Цикл событий, вращающийся в потоке, в котором живет приемник, просто захватывает QMetaCallEvents и соответственно выполняет вызовы слотов или отправляет ваши события в вашу реализацию метода customEvent().

При запуске raw QThread реализация по умолчанию метода run() включает цикл событий. Вы заметите, что такой поток фактически простаивает и не потребляет никаких ресурсов ЦП: очередь событий пуста, и цикл событий заблокирован, ожидая, что кто-то отправит событие в свою очередь. Как только вы переместите некоторые объекты QObject в такой поток, очереди с сигнальными слотами будут выполняться через цикл событий этого потока. Он работает одинаково, будь то поток GUI или любой другой поток. Поток GUI не является каким-либо особым образом, когда дело доходит до получения событий или сигналов в очереди.

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