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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Приостановка потока  (Прочитано 4103 раз)
rudireg
Гость
« : Ноябрь 04, 2016, 16:52 »

Привет. Есть поток, обрабатывающий список неких ресурсов.
Если ресурсов нет, поток должен стоять, как только он видит что появились ресурсы - поток должен начать их обработку (по кругу их постоянно обрабатывает, покуда ресурсы существуют.)

Сделал таким образом, но меня смущает sleep() -  читал что в рабочих программах применение sleep()  не очень хорошо.
Предложите альтернативу.
Код
C++ (Qt)
void Master::processAccounts()
{
   while(true){
       QApplication::processEvents();
 
       //If have not resources, then sleep
       if( !this->accountController->size() ){
           QThread::sleep(1);
           continue;
       }
 
       // Have the resources
       // Process resources ...
   };
}
 
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #1 : Ноябрь 04, 2016, 17:18 »

Использовать QWaitCondition ?
Записан

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

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Ноябрь 04, 2016, 17:20 »

timerEvent, это событие имеет неск хитростей. Оно генерируется только когда нет др событий, т.е. нет опасности что Вы будете завалены кучей timerEvent. И рекурсия автоматически рубится - когда выскочили в processEvents из timerEvent - там еще раз его не получите

Использовать QWaitCondition ?
"Ой напрасно тетя Вы таблетки пьете"  Улыбающийся
Записан
rudireg
Гость
« Ответ #3 : Ноябрь 04, 2016, 17:38 »

 В начале темы видимо я не правильно сформулировал вопрос. Нужно было не поток останавливать,  а выполнение слота.
Сделал так.

Код
C++ (Qt)
void Master::processAccounts()
{
   QEventLoop loop;
   while(true){
       QApplication::processEvents();
       if( !this->accountController->size()){
           QTimer::singleShot(1000, &loop, SLOT(quit()));
           loop.exec();
           continue;
       }
 
      // Do Pocess ...
   };
}
 
« Последнее редактирование: Ноябрь 04, 2016, 18:03 от rudireg » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #4 : Ноябрь 04, 2016, 18:13 »

В начале темы видимо я не правильно сформулировал вопрос. Нужно было не поток останавливать,  а выполнение слота.
А для чего такое делать? Расскажите, что вы хотите получить, возможно есть более правильный путь. Улыбающийся

Проверка с засыпанием не эффективна. Например, вы проверили что работы нет и заснули на 1 секунду. Через 10 мс после проверки, работа появляется, но поток не будет ее работать, он будет ждать еще 990 мс. А мог бы работать.

kuzulis правильно посоветовал (да и я вам это уже советовал) использовать для этого QWaitCondition. Он для этого и предназначен: если работы нет, поток засыпает на wait, как только работа появилась, поток будят wake.
« Последнее редактирование: Ноябрь 04, 2016, 18:32 от Old » Записан
Bepec
Гость
« Ответ #5 : Ноябрь 04, 2016, 20:41 »

Пссс... Если в его пример внедрить ещё 1 сигнал, который будет цепляться к лупу, который будет подаваться при добавлении задачи, его вариант будет удовлетворять всем требованиям Улыбающийся
Записан
rudireg
Гость
« Ответ #6 : Ноябрь 04, 2016, 21:28 »

В начале темы видимо я не правильно сформулировал вопрос. Нужно было не поток останавливать,  а выполнение слота.
А для чего такое делать? Расскажите, что вы хотите получить, возможно есть более правильный путь. Улыбающийся

Проверка с засыпанием не эффективна. Например, вы проверили что работы нет и заснули на 1 секунду. Через 10 мс после проверки, работа появляется, но поток не будет ее работать, он будет ждать еще 990 мс. А мог бы работать.

kuzulis правильно посоветовал (да и я вам это уже советовал) использовать для этого QWaitCondition. Он для этого и предназначен: если работы нет, поток засыпает на wait, как только работа появилась, поток будят wake.

Задача простая...
Программа работает со списком аккаунтов  и выполняет назначенные для них задания.
Есть объект MASTER унаследованный от QOBJECT , который перенесен в новый поток с помощью movetothread
Следовательно MASTER теперь работает на сигналах и слотах (плюс событиях).
Объект MASTER постоянно по кругу мониторит QList  аккаунтов и смотрит есть ли какие либо задания у аккаунтов.
Если задание есть, то для выполнения каждого, объект MASTER с помошью QThreadPool выполняет задания в объекте что унаследован от QRunnable

Вот я и задался вопросом, что если при старте проги, нет аккаунтов в работе, MASTER  их должен ждать, а через время аккаунты появились, тогда MASTER должен их обрабатывать.
Объект MASTER  имеет много слотов, которые могут выполнятся асинхронно... и я подумал, если использовать QWaitCondition - то он заблокирует весь поток... тогда ВСЕ СЛОТЫ объекта MASTER будут остановлены покуда не будет вызван QWaitCondition.wakeAll
А мне нужно что бы ждал только слот, что мониторит список аккаунтов....
QEventLoop  (даже с паузой 1 сек) - это выигрыш с малой кровью на мой взгляд, ибо повявление и исчезновение новых аккаунтов делается 1 или 2 раза на протяжении всей работы программы.

« Последнее редактирование: Ноябрь 04, 2016, 21:41 от rudireg » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #7 : Ноябрь 05, 2016, 08:40 »

Объект не может жить в потоке, объект это набор данных. В отдельном потоке может выполняться какой-то код. Контекст потока в Qt введен исключительно для правильной работы сигналов-слотов между потоками.
Например, у одного объекта MASTER его методы легко могут выполняться в разных потоках.
Если метод processAccounts приходится тормозить, значит его кто-то постоянно вызывает, так может не стоит его вызывать, если для него нет работы?
Записан
rudireg
Гость
« Ответ #8 : Ноябрь 05, 2016, 09:31 »

Объект не может жить в потоке, объект это набор данных. В отдельном потоке может выполняться какой-то код. Контекст потока в Qt введен исключительно для правильной работы сигналов-слотов между потоками.
Например, у одного объекта MASTER его методы легко могут выполняться в разных потоках.
Если метод processAccounts приходится тормозить, значит его кто-то постоянно вызывает, так может не стоит его вызывать, если для него нет работы?
Вы писали: Например, у одного объекта MASTER его методы легко могут выполняться в разных потоках.
Каким образом? Вы имеете ввиду использование QConcurrent и QThreadPool ?
Если взять допустим QThreadPool , то следует MASTER унаследовать от QRunnable  и вызывать QThreadPool::start(MASTER );
Верно я понял?
Не вижу другого способа выполнять методы MASTER  в иных потоках.
Хотя если тока на сигналах и слотах еще можно реализовать... один сигнал объекта MASTER  соединен с разными СЛОАТМИ других объектов, выполнение которых происходит в разных потоках.
« Последнее редактирование: Ноябрь 05, 2016, 09:35 от rudireg » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #9 : Ноябрь 05, 2016, 11:50 »

Каким образом? Вы имеете ввиду использование QConcurrent и QThreadPool ?
Не имеет значение что использовать, и QtConcurrent и QThreadPool базируются на системных потоках. Если вы запустите два потока, из первого вызовете один метод, а из другого другой, вот вам и работа в разных потоках. Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Ноябрь 05, 2016, 12:38 »

Почему не организовать обработку account банальным слот/сигналом? При обновлении accountController испускается сигнал который (через EventLoop нитки) приходит на слот Master::processAccounts, который делает DoProcess и просто завершается. Какая необходимость в организации вторичного цикла?
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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