Russian Qt Forum
Ноябрь 24, 2024, 02:44 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Есть ли рекомендации по необходимости выноса функции в поток?  (Прочитано 9271 раз)
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« : Сентябрь 23, 2016, 16:47 »

Всем доброго времени.

Вот, есть некая ф-я, на работу которой затрачивается 1-2 мсек. Есть ли необходимость выноса ее в отдельный поток?
И есть ли вообще рекомендации, когда это нужно делать (каков лимит микросекунд/миллисекунд) чтобы ГУЙ не тормозил? Улыбающийся
« Последнее редактирование: Сентябрь 23, 2016, 16:49 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #1 : Сентябрь 23, 2016, 16:51 »

Обычно считается, что от 20 обновлений в секунду человеку трудно увидеть разницу.
Поэтому 50 мсек на функцию - должно быть в пределах нормы.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Сентябрь 24, 2016, 03:10 »

По моим наблюдениям рекомендация "выноси в поток" дается на все без разбора, мотивировка "чтобы UI не тормозило". Думаю выносить или нет зависит от того есть ли что делать приложению пока ф-ция выполняется. Напр если операция чисто фоновая и может длиться хз сколько, то вынос очевиден. Но часто (если не чаще) бывает что приложению надо дождаться конца или отмены операции, а потом уже что-то решать. Здесь вынос в поток совершенно ни к чему, заморозку UI легко решить повтыкав qApp->processEvents
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Сентябрь 24, 2016, 03:20 »

Обычно считается, что от 20 обновлений в секунду человеку трудно увидеть разницу.
Поэтому 50 мсек на функцию - должно быть в пределах нормы.
Читаем классику  Улыбающийся
Цитировать
While an operation generated by a menu item takes place, you need to
provide feedback to the user about what is going on. You can display the
animated watch cursor for immediate feedback if an operation will last only a
short length of time. If the operation takes a bit longer, display a status dialog
box to give the user more feedback about the operation under way. If an
operation takes a long time, be sure to implement it asynchronously so that it
can run in the background. After the operation is completed, return the menu
title to the unhighlighted state.

Keep in mind when you decide your timing issues that people have built-in
expectations about how long they want to wait for an operation to be
completed. Try to provide your users with feedback that lets them know that
the computer is still working
Где-то еще видел: задержка до 2 сек - можно обойтись курсором, больше - надо показывать индикатор
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #4 : Сентябрь 24, 2016, 11:39 »

Цитировать
заморозку UI легко решить повтыкав qApp->processEvents

Не, ну это понятно... А вот, допустим, что ф-я какая то внешняя, библиотечная, в которую ничто не натыкаешь. Кроме того, она вызывается периодически.

Думаю, что придётся в поток вынести, т.к. кроме неё ещё могут быть и другие аналогичные, тратящие миллисекунды. Если таких ф-й наберётся достаточно, то ЮИ будет фризиться.

Хотя, конечно, лучше пройтись профилировщиком сначала, а потом думать.  Улыбающийся
Записан

ArchLinux x86_64 / Win10 64 bit
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Сентябрь 24, 2016, 13:10 »

Думаю, что придётся в поток вынести, т.к. кроме неё ещё могут быть и другие аналогичные, тратящие миллисекунды. Если таких ф-й наберётся достаточно, то ЮИ будет фризиться.
Заморозка/разморозка - палка о двух концах. Разгружая нитку UI Вы должны считаться с текущими операциями в др нитках. Напр юзер повторно запускает операцию которая уже выполняется или закрыл окно куда должны прийти данные или вообще хочет выйти из приложения и.т.п. Нередко предусмотреть все оказывается слишком сложным
Записан
qate
Супер
******
Offline Offline

Сообщений: 1177


Просмотр профиля
« Ответ #6 : Сентябрь 24, 2016, 18:29 »

Думаю, что придётся в поток вынести

а какие сложности использовать QtConcurrent ?
там и поток создается и результат вернется, ничего самому делать не нужно
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #7 : Сентябрь 26, 2016, 12:13 »

имхо, выносить в поток или нет зависит от ситуации. Я бы не стал выносить в поток ради антифриза ГУИ и функцию, которая работает 3 сек если она всегда вызывается весьма редко.
С другой стороны, если рассматривать сохранение большого объекта в файл и дальнейшее продолжение работы, то можно в поток передать копию сохраняемого объекта.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #8 : Сентябрь 26, 2016, 14:00 »

Цитировать
а какие сложности использовать QtConcurrent ?

В принципе - никаких. Кроме как то что прервать нельзя (вроде как).
Записан

ArchLinux x86_64 / Win10 64 bit
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #9 : Сентябрь 26, 2016, 16:01 »

kuzulis, прервать можно. У вас поток выполнения будет считывать флаг прерывания и прекращать работу в случае истины, а ГУИ, имея указатель на эту переменную, имеет возможность установить в него значение.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #10 : Сентябрь 27, 2016, 09:23 »

Цитировать
прервать можно
А если ф-я не моя, и не имеет исходников? (если она резолвится?)  Подмигивающий
Туда некуда флаг засовывать.

Цитировать
У вас поток выполнения будет считывать флаг прерывания и прекращать работу в случае истины,
 а ГУИ, имея указатель на эту переменную, имеет возможность установить в него значение.

Это гемморой. Там с мьютексами огород нужен и прочее... (как я понял, предлагается QThread::run() ??).
Я как раз хочу от этого избавиться.

Хочу все асинхронно - запустил ф-ю в треде и забыл про нее... когда она отработает - я просто получу уведомление.
Все!

Плохо что прервать нельзя. По крайней мере в доках написано, что QFutureWatcher, полученный от QtConcurrent::run()
не "канселябельный", но вроде как, полученный от мапы "канселябельный"... Надо поизучать этот момент. Улыбающийся

PS: В рассылке мельком видел предложение, чтобы ввести" платформо-специфичные" вещи для возможности
прерывания потока без всяких флагов: http://lists.qt-project.org/pipermail/development/2016-September/026939.html
(хотя, вроде там не об этом речь)
« Последнее редактирование: Сентябрь 27, 2016, 09:28 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #11 : Сентябрь 27, 2016, 09:34 »

Цитировать
А если ф-я не моя, и не имеет исходников? (если она резолвится?)
Мне кажется, что для такого случая подходит только убить нитку (QtConcurent не предоставляет такой возможности), но это чревато последствиями. Так что, на мой взгляд, такую функцию лучше не прерывать либо вынести её в отдельный исполнительный файл.

Цитировать
Это гемморой. Там с мьютексами огород нужен и прочее...
Если вы хотите просто, чтобы интерфейс не застывал, то мьютексы не понадобятся. У вас запись в переменную ведёт только 1 поток, второй же просто считывает её. Для этого не нужны блокировки.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #12 : Сентябрь 27, 2016, 09:39 »

Цитировать
либо вынести её в отдельный исполнительный файл.

Да, кстати, а QProcess - это вариант! Если и крешнится там что-нить из той ф-ции, то это не проблема.  

Пусть тот процесс висит и ждет команд через пайпы и возвращает результат через пайпы..
Записан

ArchLinux x86_64 / Win10 64 bit
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #13 : Сентябрь 27, 2016, 12:54 »

Да, кстати, а QProcess - это вариант!
Куда понесло? ("пришел за памперсами"  Улыбающийся)

Хочу все асинхронно - запустил ф-ю в треде и забыл про нее... когда она отработает - я просто получу уведомление.
Все!
Это хорошо для операций длящихся хотя бы хорошие доли секунды, а иначе - разбазаривание ресурсов, вызов обойдется дороже.

Думаю, что придётся в поток вынести, т.к. кроме неё ещё могут быть и другие аналогичные, тратящие миллисекунды. Если таких ф-й наберётся достаточно, то ЮИ будет фризиться.
Ну и кто мешает воткнуть qApp->processEvents после того как ф-ция вернула управление? Наверное только неукротимое желание познать "многопоточность"  Улыбающийся
Записан
Akon
Гость
« Ответ #14 : Сентябрь 28, 2016, 19:27 »

Имхо, миллисекунды - это ни о чем. Даже если таких функций несколько, и между ними у ГУЯ будет возможность обработать события из очереди, - никаких значимых тормозов.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.055 секунд. Запросов: 23.