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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: ThreadControl suspend/resume/abort  (Прочитано 9890 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Январь 30, 2016, 15:13 »

Добрый день

Навеяно этой темой. Полагаем что мы не используем QThread::exec, а сами делаем все свои дела в QThread::run. И вот казалось бы, "простейшая задача" - надо нитку остановить а потом снять с останова. Но я не вижу никакого простого способа это сделать. Если чего-то не нашел - please "ткните носиком" Улыбающийся

Не, ну конечно можно так
Код
C++ (Qt)
void MyThread::run( void )
{
while (!mAbortFlag) {
 while (mPauseFlag)
   msleep(SOME_DELAY);
 
  // do job
}
}
Несмотря на привлекающую простоту использование sleep в рабочем коде (не для отладки/примера) надо признать малодушным решением. Кроме того здесь протаскивается предположение что управляющая нитка (которая меняет mAbortFlag и mPauseFlag) всего одна, напр главная. Как только их будет 2 и больше - так просто уже не выйдет.

В аттаче попытка сделать "по-взрослому", с ожиданием на семафоре. Ф-ционал собран в отдельный класс который можно цеплять членом или множ наследованием к QThread но не только.

Примечание для тех у кого опыта мало
Цитировать
Я вот нажал Enter, напечатала "Suspended..", потом еще все нитки сработали по разу...
Это нормально, "мгновенно" нитку не остановить, дело должно дойти до проверки

Это все, благодарю за внимание
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #1 : Январь 30, 2016, 16:08 »

Ну теперь понятно, каким боком вы туда семофор сватали. Улыбающийся Но у автора той темы один флаг с условной переменной на все потоки (для пула так удобней), а у вас по семафору на поток.

В аттаче попытка сделать "по-взрослому", с ожиданием на семафоре.
А в чем вы видите взрослость решения? Мне это напомнило: "Мы научим вас делать сложно простые вещи". Улыбающийся

Я вообще не понимаю, где может понадобиться установка потока на паузу? Рабочие потоки могут спать в ожидании работы, их нужно остановить при завершении работы программы, но поставить их на паузу? Для чего?
« Последнее редактирование: Январь 30, 2016, 16:12 от Old » Записан
AkonResumed
Чайник
*
Offline Offline

Сообщений: 81


Просмотр профиля
« Ответ #2 : Октябрь 18, 2020, 20:37 »

Ну, например, в Win API есть ref-counted SuspendThread/ResumeThread. Элементарный юзкейс - например, вычисляете 10-ю потоками некое сложное значение, юзер ждет, но решает поставить операцию на паузу и выполнить другое жирное вычисление.

Т.е. такие функции (заметьте, они со счетчиком, и могут быть заюзаны из разных потоков) избавляют от замусоливания рабочего кода всякими проверками флагов паузы.
« Последнее редактирование: Октябрь 18, 2020, 20:40 от AkonResumed » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Октябрь 19, 2020, 12:29 »

Ну, например, в Win API есть ref-counted SuspendThread/ResumeThread. Элементарный юзкейс - например, вычисляете 10-ю потоками некое сложное значение, юзер ждет, но решает поставить операцию на паузу и выполнить другое жирное вычисление.

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

Цитировать
Эта функция, прежде всего, разработана для использования отладчиками. Она не предназначена использоваться для синхронизации потока. Вызов функции SuspendThread потоком, который имеет объект синхронизации, типа мьютекса (флажка блокировки) или критической секции, может привести к тупиковой ситуации, если вызывающий поток пробует получить объект синхронизации, принадлежащий приостановленному потоку. Чтобы избежать этой ситуации, поток в пределах прикладной программы, которое не является отладчиком, должен подать сигнал другому потоку, что приостановил себя. Целевой поток должен быть разработан, чтобы наблюдать за этим сигналом и соответственно реагировать.
И тут не все просто как хотелось бы. И, кстати, интересно какова скорость срабатывания такого suspend/resume

Элементарный юзкейс - например, вычисляете 10-ю потоками некое сложное значение, юзер ждет, но решает поставить операцию на паузу и выполнить другое жирное вычисление.
Неплохой пример, но все же надо заметить что "другое жирное" будет выполнено др нитками, хотя да, быстрее (нагрузку на ядра мы уменьшили)
Записан
AkonResumed
Чайник
*
Offline Offline

Сообщений: 81


Просмотр профиля
« Ответ #4 : Октябрь 19, 2020, 22:55 »

Некросплатформенно, это Win API. Я привел пример, когда постановка потока на паузу оправдана, более того, этот функционал есть в Win API, системы, над которой работало не самое малое количество далеко не самых последних инженеров, - согласитесь, это имеет вес.

Скорость переключения? Cерьезно?.. ~ 2000 аccемблерных инструкций на x86 (переход в режим ядра), то же, что и у Sleep.
Записан
tux
Global Moderator
Бывалый
*****
Offline Offline

Сообщений: 404



Просмотр профиля
« Ответ #5 : Октябрь 19, 2020, 22:59 »

Некросплатформенно, это Win API.
Ну и на кой ляд оно в 2020 году? Тем более в Qt.
Записан

AkonResumed
Чайник
*
Offline Offline

Сообщений: 81


Просмотр профиля
« Ответ #6 : Октябрь 20, 2020, 10:01 »

Я вовсе не агитирую за агульное применение! Просто проиллюстрировал, что подобный функционал (постановка потока на паузу) востребован.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Октябрь 20, 2020, 10:56 »

этот функционал есть в Win API, системы, над которой работало не самое малое количество далеко не самых последних инженеров, - согласитесь, это имеет вес.
Не разделяю восторгов по поводу Вын API, вынужден поддерживать эту платформу но это, пожалуй, одна из самых неприятных частей работы. Тем не менее, о возможности делать это "через ОС" не знал, спасибо

Я вовсе не агитирую за агульное применение! Просто проиллюстрировал, что подобный функционал (постановка потока на паузу) востребован.
Да. Далеко не всегда удается разделить задачу на (достаточно мелкие) "порционные куски" что могут выполняться любой ниткой. Это как бы "идеальный вариант" к которому надо стремиться.
Записан
tux
Global Moderator
Бывалый
*****
Offline Offline

Сообщений: 404



Просмотр профиля
« Ответ #8 : Октябрь 20, 2020, 13:40 »

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

RedDog
Частый гость
***
Offline Offline

Сообщений: 221


Просмотр профиля
« Ответ #9 : Октябрь 20, 2020, 17:43 »

а какой нибудь std::condition_variable::wait() нельзя было заюзать?
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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