Форум программистов, компьютерный форум, киберфорум
C++ Qt
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.82/89: Рейтинг темы: голосов - 89, средняя оценка - 4.82
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30

О странностях QtConcurrent+QFuture+QFutureWatcher

22.01.2015, 13:24. Показов 17694. Ответов 36
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Вот такой код работает:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
QString threadFunc()
{
  return QString("This is result");
}
 
QFutureWatcher<QString> watcher; // Глобальное объявление ???
QFuture<QString> future;
 
void MainWindow::on_pushButton_clicked()
{
  connect(&watcher,SIGNAL(finished()),
          this,   SLOT(on_finished()));
 
  watcher.setFuture(future);
  future = QtConcurrent::run(threadFunc);
}
 
void MainWindow::on_finished()
{
 QString text=  future.result();
 ui->textBrowser->insertPlainText(text);
}
Первый момент: Вопрос а что делать, если мне нужно несколько потоков запустить по мере появления данных, как получить каждый результат future.result() из слота on_finished и отличить их один от другого?
Как правильно распоряжаться объектами QFuture/QFutureWatcher в плане создания/уничтожения?

Второй момент: Почему код перестает работать при замене на
C++ (Qt)
1
2
3
4
5
void MainWindow::on_finished()
{
  QString text=  watcher.future().result(); //  через watcher !!!   Приложение падает
   ui->textBrowser->insertPlainText(text);
}
Но стоит сделать еще одну правку:
C++ (Qt)
1
2
3
4
5
6
7
void MainWindow::on_pushButton_clicked()
{
  connect(&watcher,SIGNAL(finished()),
          this,   SLOT(on_finished()));
 
  watcher.setFuture(QtConcurrent::run(threadFunc));  // прямиком в watcher !!!
}
Все ок!
Я так понимаю лажа с подсчетом ссылок и правами владения?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
22.01.2015, 13:24
Ответы с готовыми решениями:

QtConcurrent::run() многоразовый вызов, очередность получения QFuture::result()
Задача следующая - есть файл, большой файл. Нужно провести по нему определенные операции - декодирование. Однопоточно это делать медленно,...

QFutureWatcher progressTextChanged
Доброго времени суток. На основе примера делаю свой прогресс-диалог и возник вопрос, как сделать чтобы QFutureWatcher посылал сигнал...

И еще раз о странностях ранжирования Гугла
Чтобы окончательно не запутаться в лабиринтах логики Гугла, вопрос к гуру: наш сайт kirillovka(тчк)com(тчк)ua по запросу...

36
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
22.01.2015, 16:38  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от RazrFalcon Посмотреть сообщение
Avazart, так есть разница или нет?
В данном пример: кроме того что слот будет обработан через 30сек - нет. Т.е слот не будет пропущен.
0
 Аватар для RazrFalcon
1403 / 1260 / 262
Регистрация: 10.11.2013
Сообщений: 3,763
22.01.2015, 16:46
Avazart, понятно.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
22.01.2015, 16:51  [ТС]
Это аналогично фрагменту кода работы с QNetworkAccessManager
C++ (Qt)
1
2
3
4
QNetworkReply* reply=  manager->get(request);
 
   connect( reply, SIGNAL(finished()),
            this, SLOT(replyFinished()) );
Я долго не мог в него врубится.
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
22.01.2015, 17:16
Цитата Сообщение от Avazart Посмотреть сообщение
Да он о то может завершится раньше и выслать сообщение, но сообщение может обработано только после завершения слота кнопки.
Если QFuture отработает до того, как создастся подключение через QObject::connect, то посылки сигнала не будет.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
22.01.2015, 17:20  [ТС]
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
Если QFuture отработает до того, как создастся подключение через QObject::connect, то посылки сигнала не будет.
Ну так отрабатывает и слот вызывается... если мой проверочный код некорректен то в чем?
Хотя стоило бы проверить этот код и на других платформах, не только под Windows.
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
22.01.2015, 18:16
Цитата Сообщение от Avazart Посмотреть сообщение
Ну так отрабатывает и слот вызывается... если мой проверочный код некорректен то в чем?
Я прокоментировал к чему относится цитата из книги, а относится она к void QFutureWatcher::setFuture
To avoid a race condition, it is important to call this function after doing the connections.
В этом коде:
C++ (Qt)
1
2
3
4
5
6
QFuture<quint64> future;
QFutureWatcher<quint64> watcher;
connect(&watcher, SIGNAL(finished()), this, SLOT(finished()));
watcher.setFuture(future);
qint32 n = 100;
future = QtConcurrent::run(fibonacci, n);
явная ошибка. Внутри setFuture происходит копирование экземпляра QFuture.
0
22.01.2015, 18:22  [ТС]

Не по теме:

Цитата Сообщение от Dmitriy_M Посмотреть сообщение
Внутри setFuture происходит копирование экземпляра QFuture.
Да, это уже выяснили, я просто увидев этот код думал что QFuture - хитрый тип к примеру с подсчетом ссылок что позволят такое вытворять, ведь странно то что сделали передачу значения future, а не указателя.

0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
22.01.2015, 18:37
Цитата Сообщение от Avazart Посмотреть сообщение
я просто увидев этот код думал что QFuture - хитрый тип к примеру с подсчетом ссылок что позволят такое вытворят
1 это поведение противоречит стандартному поведению в C++;
2 такое поведение не реализуется подсчетом cсылок.
Цитата Сообщение от Avazart Посмотреть сообщение
ведь странно то что сделали передачу значения future, а не указателя.
такой подход позволяет избежать проблем с указателями.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
22.01.2015, 18:45  [ТС]
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
1 это поведение противоречит стандартному поведению в C++;
Да как бы и задача то нестандартная, к тому же фиг его знает что они туда по-запихали.
Ведь watcher принял невалидный future, спрашивается чего не запретить такое действие? Да и вообще конструирование не из QtConcurrent::run().

Хотя опять же я забываю про то что Qt избегает исключений.
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
22.01.2015, 19:12
Цитата Сообщение от Avazart Посмотреть сообщение
Да как бы и задача то нестандартная
почти стандартная std::future
Цитата Сообщение от Avazart Посмотреть сообщение
Ведь watcher принял невалидный future
валидный, но пустой
0
22.01.2015, 19:34  [ТС]

Не по теме:

Цитата Сообщение от Dmitriy_M Посмотреть сообщение
валидный, но пустой
ну валидным он становится когда привязан к задаче, а так...
Добавлено через 16 минут
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
почти стандартная std::future
Ну я плохо знаю стандарт, но вероятно это
http://en.cppreference.com/w/c... red_future
то про что я хотел сказать.

А именно то что вероятно лучше было бы возвращать умный указатель на Future, а не его локальный объект.

0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
22.01.2015, 19:44

Не по теме:


Цитата Сообщение от Avazart Посмотреть сообщение
ну валидным он становится когда привязан к задаче,
С точки зрения ООП и контрактного программирования все ОК.


Возможно QRunnable вам подходит лучше QFuture.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
22.01.2015, 19:50  [ТС]
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
Возможно QRunnable вам подходит лучше QFuture.
А чем лучше QRunnable ?
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
22.01.2015, 19:57
Тем, что не нужен дополнительный инструмент в виде QFutureWatcher.
Передаешь готовый результат в нужный метод через QMetaObject::invokeMethod.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
22.01.2015, 20:04  [ТС]
Ну так а для QMetaObject::invokeMethod нужно наследоваться, так что в принципе тоже самое.
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
22.01.2015, 20:26
Для QMetaObject::invokeMethod наследоваться не нужно, нужно наследоваться от QRunnable и переопределить run.
Если выставить авто удаление, то не нужно заботиться об удалением.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
22.01.2015, 21:56  [ТС]
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
нужно наследоваться от QRunnable и переопределить run.
Да я это и мел ввиду.
Как бы никто не мешает его вызывать ф-ции переданной в QtConcurrent::run().

Добавлено через 4 минуты
Цитата Сообщение от RazrFalcon Посмотреть сообщение
Avazart, неправильный мой пример был. Вот верный вариант: http://qt-project.org/doc/qt-4... ultReadyAt
То есть сигнал есть с указанием какой результат можно забирать когда он готов.
Кстати как я понимаю resultReadyAt(), canceled (), progressRangeChanged () только для обработки коллекций?
(т.е отображений,фильтров, редуктров).
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
22.01.2015, 21:56

QtConcurrent
Здравствуйте, хочу сделать сервер многопоточным, через concurrent. Делаю так void chatServer::incomingConnection(int desc) { ...

QtConcurrent и bind
Доброго времени суток. Есть вот такой незамысловатый код: #include &lt;QCoreApplication&gt; #include &lt;QDebug&gt; #include...

Не работает QtConcurrent
void Object::loadObjModel(const std::string filename) { .... std::string line; while(std::getline(object, line)) ...

QtConcurrent::mapped
Заранее извиняюсь. Вопрос достаточно глупый, но всё же QStringList lst (QStringList ( ) &lt;&lt; &quot;one&quot; &lt;&lt; &quot;two&quot;...

Использование в qtconcurrent::run() ui->
Доброго времени, форумчане! При сабже программа вылетает. Как быть? Возможно ли из лямбды послать сигнал(как же по-нубски звучит этот...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
37
Ответ Создать тему
Новые блоги и статьи
Nekobox - outbounds[0].transport: unknown transport type: raw
damix 01.10.2026
Фикс ошибки Правым кликом по серверу -> отладочная информация -> edit Заменить "net": "raw", на "net": "tcp", Нажать кнопку reload.
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru