Как стать автором
Обновить

Комментарии 11

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

Я конечно могу ошибаться с последними версиями Qt, но ранее предварительной регистрации типов аргументов для передачи через слоты и сигналы не было. В документации по слотам и сигналам нет упоминаний об этом тоже. Откуда вас информация что требуется использовать qMetaType? ЕМНИП он требуется в том случае если мы говорим о регистрации нового типа данных для обработки в QVariant.

Регистрация нужна, когда вы передаёте данные сигналом через очередь событий (между потоками или когда связка сделана через QueuedConnection).
Я бы это вообще не упоминал, в Qt есть достаточно базовых типов, которые уже везде зарегистрированы и не несут практически никакого оверхеда. Например, QByteArray

Как заметил Sazonov можно использовать тип QByteArray. Но с ним у меня не получилось наглядно увидеть эффект грязного чтения. Кому интересно вот код из статьи, но с QByteArray

В целом, мне кажется выбранная вами тема очень слабовата для статьи. В документации по Qt или на stackoverflow есть более исчерпывающие примеры того, что вы описываете.
Теперь по коду:
1) У вас текут ресурсы. Ваш Worker, ваш thread — не предусмотрена остановка потока и удаление объектов.
2) Если основной ваш посыл в отсутствии зависаний в интерфейсе, то зачем вы морозите GUI потом таким циклом. Если уж сильно хочется, то дёрните просто QThread::sleep.
3) Зачем все эти велосипеды с регистрацией типов? Формируйте данные для GUI сразу в рабочем потоке и отправляйте через сигнал — тогда у вас действительно задержки будут минимальные.

По поводу текущих ресурсов. Если я вместо


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    thread = new QThread;

Буду писать


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , thread(new QThread)
{

У меня перестанут течь ресурсы из-за thread?
smurfomen

Нет, не перестанут. Советую прочитать про основы модели памяти в Qt. В частности про отношения parent-child.

QtConcurrent хорош если надо единоразово запустить задачу на выполнение в отдельном потоке и по выполнению получить какой-то результат. Если нужен воркер, постоянно работающий в отдельном потоке и раз в какое-то время отправляющий что-то в гуй, лучше как раз QObject, QThread со своей очередью событий и moveToThread.

Это верно. Кстати хороший пример практического использования QtConcurrent

  1. В официальной документации больше информации, если конечно не читать старую от нокиа, в которой переопределяли метод QThread::run().
  2. Нет ни слова про afinity.
ну так чуть раскидаю:
1. Как сказано выше — у вас реально течет.
2. Для объявления слотов одного Q_OBJECT будет недостаточно, вам нужно полное наследование от QObject. Q_OBJECT отвечает за декларацию типа как базового от QObject для MOC.
3. Связка сигнал-слот априори медленнее чем вызов функции, т.к. механизм сигналов и слотов работает по принципу callback'ов, только после вызова прокручивается весь список подписанных на сигнал этого объекта слотов, проверяются сигнатуры и т.д, весь этот процесс — дорогое удовольствие, и за это мы платим временем. Отсюда вывод — механизм сигнал-слотов НЕ потокобезопасен, слот не должен пользоваться разделяемыми ресурсами или вы должны оградить их блокировкой, но тут вы не угадаете кем, например, первее будет захвачен mutex.
4. Никогда не делайте выполнение слота в вызывающем потоке (Ваш модификатор BlockingQueuedConnection). Особенно GUI, любая неполадка или задержка в GUI сломает вам процесс. Более того — вы изменяете состояние GUI из смежного потока, пусть и в его же слоте. Решением же в вашем случае с массивом может быть только передать в слот кадр этого массива, либо работайте с динамически изменяемыми данными, но стоит ли отдавать что то в слот по указателю — решать конечно вам, от себя лишь скажу, что это по меньшей мере безрассудно.
P.S. последнее, про переопределение типов — признаться, не смог понять зачем вы это здесь написали, к теме не относится
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации