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

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

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: waitForDone  (Прочитано 11890 раз)
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


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


Просмотр профиля
« Ответ #15 : Июль 06, 2021, 10:46 »

Ну, архитектуры тут нету, это чисто вопрос дизайна приложения.
Да, "плохая задача", инфа 99% Улыбающийся
Поскольку это "главный" поток, подвешивать его в цикле - это моветон.
Задайте себе вопрос: а почему, собственно, он должен ждать?
Что происходит в момент ожидания?
Что видит юзер в этот момент? Прогресс бар или спиннер? В этом случае надо бы события обрабатывать.
Если же так прямо надо подвеситься, то проще всего решается поллингом воркера. Типичное не модное, но рабочее решение "без зауми".
Записан

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


Просмотр профиля
« Ответ #16 : Июль 06, 2021, 12:53 »

Если же так прямо надо подвеситься, то проще всего решается поллингом воркера. Типичное не модное, но рабочее решение "без зауми".
"А я шо делаю?" (как говорят в моем регионе). while m_TaskCount и есть поллинг. Но все-таки sleep - это моветон. Где все эти прелести std:: которые якобы "тупо лучше" ? Макс, где Ваш "вариант с футурами"? Улыбающийся

Кстати, "контроль кода" в Вашей компании пропустит sleep в цикле ?

Поскольку это "главный" поток, подвешивать его в цикле - это моветон.
Задайте себе вопрос: а почему, собственно, он должен ждать?
Что происходит в момент ожидания?
Что видит юзер в этот момент? Прогресс бар или спиннер? В этом случае надо бы события обрабатывать.
Ну это рекомендации что даются другим, сам дающий следовать им не будет Улыбающийся Ну вот хотя бы отмена фоновой операции. Да, выставил флажок abort для воркера, но дождаться обязан, рыпаться с др событиями пока ресурс(ы) захвачен воркером - себе дороже
Записан
RedDog
Частый гость
***
Offline Offline

Сообщений: 221


Просмотр профиля
« Ответ #17 : Июль 06, 2021, 13:44 »

С применением std & boost, но принцип будет понятен:

Код:
std::string fullConfig;
std::condition_variable waiter;
auto configHandler = [&waiter](const std::string& configStr, bool)
{
    fullConfig = configStr;
    waiter.notify_all();
};

boost::asio::io_context ctx;
ConfigReaderWorker worker(ctx, settings, configHandler);
std::thread configThread = std::thread(std::bind([&ctx](){ctx.run();}));

std::mutex locker;
std::unique_lock lock(locker);
waiter.wait_for(lock, []{return !fullConfig.empty();});

worker.stop();
ctx.stop();

Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #18 : Июль 06, 2021, 15:10 »

Цитировать
Синхронка не есть "плохо", она менее гибка, но есть масса ситуаций когда нельзя связываться с др событиями пока данная  (крытыческая) часть кода не завершена. Поэтому иногда ожидание неизбежно/необходимо. А сколько рабочих ниток (одна или N) - чисто специфика задачи.
Да, согласен, в некоторых специфичных задачах это может иметь место. Кстати, недавно же обсуждали подобную проблему: http://www.prog.org.ru/topic_32489_0.html.
Сошлись на том, что thread_pool оптимальное решение) + wrapper_pool)
« Последнее редактирование: Июль 06, 2021, 15:12 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


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


Просмотр профиля
« Ответ #19 : Июль 06, 2021, 19:03 »

Ну это рекомендации что даются другим, сам дающий следовать им не будет Улыбающийся Ну вот хотя бы отмена фоновой операции. Да, выставил флажок abort для воркера, но дождаться обязан, рыпаться с др событиями пока ресурс(ы) захвачен воркером - себе дороже

Почему же, "сам так делал". Именно что диалог показывал, где прогресс бар и кнопка отмены была. В диалоге ждал, пока воркер или отработает, или отвалится по кнопке.
Ну вернее как ждал, это QProgressDialog ждал, но он то модальный.
Нажал юзер кнопку - шлем воркеру отмену и когда отменил, то прячем диалог.
Записан

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 не волк, в лес не уйдёт
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


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


Просмотр профиля
« Ответ #20 : Июль 06, 2021, 19:06 »

Кстати, "контроль кода" в Вашей компании пропустит sleep в цикле ?

А что не так со слипом в цикле? Слип останавливает поток на некоторое время, ресурсы проца не жрутся.
Не вижу, почему это плохо Улыбающийся
Записан

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 не волк, в лес не уйдёт
RedDog
Частый гость
***
Offline Offline

Сообщений: 221


Просмотр профиля
« Ответ #21 : Июль 06, 2021, 19:29 »

А что не так со слипом в цикле? Слип останавливает поток на некоторое время, ресурсы проца не жрутся.
Не вижу, почему это плохо Улыбающийся
Потому что поток стоит, а мог бы работать. Да и проц нечего экономить, пусть трудится.
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


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


Просмотр профиля
« Ответ #22 : Июль 06, 2021, 23:51 »

Потому что поток стоит, а мог бы работать. Да и проц нечего экономить, пусть трудится.

Ну поток не грузовик, он когда не работает, дорогу не занимает)
Тем более в это время другие потоки шуруют во всю, если надо.
Записан

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 не волк, в лес не уйдёт
RedDog
Частый гость
***
Offline Offline

Сообщений: 221


Просмотр профиля
« Ответ #23 : Июль 07, 2021, 09:17 »

Потому что поток стоит, а мог бы работать. Да и проц нечего экономить, пусть трудится.

Ну поток не грузовик, он когда не работает, дорогу не занимает)
Тем более в это время другие потоки шуруют во всю, если надо.
ОС контексты потоков все равно переключает, ей не важно спит он или нет.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #24 : Июль 07, 2021, 10:59 »

...в некоторых специфичных задачах это может иметь место.
Опять интересно наблюдать разницу между собственными решениями и раздаваемыми рекомендациями  Улыбающийся Помнится сами Вы ждали на мешке футур и ни о какой "асинхронке" и не помышляли.

Почему же, "сам так делал". Именно что диалог показывал, где прогресс бар и кнопка отмены была. В диалоге ждал, пока воркер или отработает, или отвалится по кнопке.
Ну вернее как ждал, это QProgressDialog ждал, но он то модальный.
Нажал юзер кнопку - шлем воркеру отмену и когда отменил, то прячем диалог.
Да, в моей практике этот вариант тоже самый популярный. Но разве это "честная" асинхронка? Нет, события выполняются лишь для модального окна (индикатор прогресса). Это модальная задача, а вовсе не фоновая. И это нормально, обычно др выхода просто нет. В фоне хорошо файл качать который самому не нужен (во всяком случае пока). А если обновляются активные, рабочие данные, отображаемые в UI - какой там нафиг "фон", все сразу рухнет

Кстати есои мы уж так идейны/принципиальны - то давайте заодно рассмотрим и асинхронный вариант, для него ведь тоже решений не видно (пока)
« Последнее редактирование: Июль 07, 2021, 11:13 от Igors » Записан
RedDog
Частый гость
***
Offline Offline

Сообщений: 221


Просмотр профиля
« Ответ #25 : Июль 07, 2021, 11:19 »

Кстати есои мы уж так идейны/принципиальны - то давайте заодно рассмотрим и асинхронный вариант, для него ведь тоже решений не видно (пока)
Код:
void MainThreadWorker::onFinishShadowThread()
{
    emit workShadowThread(/* work params */)
}
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #26 : Июль 07, 2021, 11:27 »

А что не так со слипом в цикле? Слип останавливает поток на некоторое время, ресурсы проца не жрутся.
Не вижу, почему это плохо Улыбающийся
Да, но так мы расписываемся типа "я маленький, сделать нормально не могу, вот сделал кое-как, не бейте". Но мы же не такие, правда?  Улыбающийся

Если "чисто объективно" то уязвимое место - сколько ms? Очевидно что если потребуется "выжвть все"  то sleep не годится. Словом, неполноценное и малодушное рещение
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #27 : Июль 07, 2021, 12:12 »

С применением std & boost, но принцип будет понятен:
Вот я хочу работать так
Типовое использование
Код
C++ (Qt)
// main thread
for (...) {
 ...
 if (..)
  emit SignalDoSomething(options);  // QThreadPool::addTask(options)
 ..
}
waitForDone();
Накидал задач и жду пока все сварится
Лично мне это кажется разумным и удобным. Наделал сигналов, связал их с воркером, и просто посылаю "по ходу дела", знать не знаю ни о каких очередях, синхронизации и.т.п. Параметры задачи передаю прямо в аргументах сигнала, остальное сделает Qt.

И тут ..
Код:
std::string fullConfig;
std::condition_variable waiter;
auto configHandler = [&waiter](const std::string& configStr, bool)
на меня выливают целое ведро .. "новых технологий" Улыбающийся И что, нужно срочно бежать все это учить? (включая дуст). То что я юзал уже не годится, устарело ("Qt только для UI"). Или как?  Улыбающийся

Ну ладно, попробуем разобраться. Опять та же непонятка: как Вы собираетесь "подкидывать задачи по ходу дела"? Я просто сигналами, а Вы? Какой-то fullConfig, откуда его брать - хз.

Вообще, насколько это "адекввтно"? Нужны ли такие средства для решения задачи что выглядит весьма скромно? (waitForDone)
Записан
RedDog
Частый гость
***
Offline Offline

Сообщений: 221


Просмотр профиля
« Ответ #28 : Июль 07, 2021, 13:17 »

Ну ладно, попробуем разобраться. Опять та же непонятка: как Вы собираетесь "подкидывать задачи по ходу дела"? Я просто сигналами, а Вы? Какой-то fullConfig, откуда его брать - хз.

Вообще, насколько это "адекввтно"? Нужны ли такие средства для решения задачи что выглядит весьма скромно? (waitForDone)
Я просто скопипастил кусок своего кода и рабочего проекта. Буст там исключительно для асинхронности (от Qt отказываемся).
Смысл в том, чтобы запустить параллельную задачу, встать на wait_condition и ждать пока в лямбде этот wait_condition не занатифает кто либо из параллельного потока.
Замените бустовый контекст на QThread а лямбду на слот, и получится то же самое.

upd:
нашел еще один проект, с похожей асинхронкой, почистил от всего лишнего, может натолкнет на мысли
« Последнее редактирование: Июль 07, 2021, 13:41 от RedDog » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #29 : Июль 07, 2021, 13:49 »

Смысл в том, чтобы запустить параллельную задачу, встать на wait_condition и ждать пока в лямбде этот wait_condition не занатифает кто либо из параллельного потока.
Это понял, но тогда надо засисять доступ к fullConfig (по сути очередь), а делать это обычно неудобно, напр очередь пуста, но последняя задача еще тикает.

Конечно охаять чужой код - много ума не надо, но впечатление что с "современным С++" забот заметно больше - и очередь (аналог), и примитив синхронизации - все то чего хотелось избежать Улыбающийся

Да, а "послать чистый лист бумаги" - так никто и не допер? Плачущий Не может быть, наверное это просто "слишком очевидно"  Улыбающийся
« Последнее редактирование: Июль 07, 2021, 13:51 от Igors » Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


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