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

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

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

Сообщений: 11445


Просмотр профиля
« : Ноябрь 18, 2014, 10:45 »

Автор заблокировал тему (видимо раздражен ответами), поэтому прошу простить мою навязчивость  Улыбающийся
Цитировать
Причем запускает он её не простым стартом QThread, а снятием ранее запущенной нити, которая к этому времени находится в WaitCondition. То есть, основной процесс-приемник сигнала делает wakeOne() для ожидающей нити, после того, как разобрал данные и подготовил для обработки. И сразу, как только он разбудил обработчик, основной процесс приостанавливается на своём WaitCondition (иначе он начинает ловить следующие входящие сигналы, и начинается чехарда при подготовке данных, которые никто не успевает обработать). Когда обработка закончена, 3я нить снимает основной процесс с ожидания вызовом wakeOne() сама снова становится в WaitCondition, и приём повторяется
Возможно это типичная ошибка "wakeOne будит нитку". Это не совсем так, побудка не имеет эффекта если нет нити(ей) ожидающих на WaitCondition, и проблема в том что Вы никак не можете узнать сидит она на wait или нет. Поэтому ожидающая нитка должна сама страховаться, напр     
Код
C++ (Qt)
while (true) {
mutex.lock();
while (data.size() == 0)
 condition.wait(&mutex);
// do something
mutex.unlock();
}
Напр нитка делает mutex.lock() (вторая строчка), но получилось так что кто-то другой захватил мутекс и сделал wakeOne - который никого не разбудил. Тогда нитка проверила что уже есть данные в data (вот страховка) и не стала никого ждать.

Эта схема часто применяется для выборки из очереди, т.е. когда кладут и изымают из одного контейнера. Если такой необходимости нет, то на QSemaphore получается проще и приятнее
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Ноябрь 19, 2014, 16:19 »

Автор успел создать новую тему и опять ее заблокировать Улыбающийся По ходу дела ему был дан такой совет
Цитировать
Есть поток с while(running) { }. Нужно его приостановить и продолжить работу. Например поток шлет данные. Либо поток хэндлить входящие данные. Много ситуаций.
Иногда он не нужен, но зачем его прибивать, если можно просто поставить в wait на время и не инициализировать заново.

Код
C++ (Qt)
void MyThread::run() {
   // init
   mContinue = new QMutex;
   mWaitCondition = new QWaitCondition;
 
   while(running) {
       lock();
       // do stuff
       unlock();
 
       if (pause) {
           mWaitCondition->wait(mContinue);
       }
 
       exec();
   }
}
 
void MyThread::pause() { pause = true; }
 
void MyThread::resume() {
   if (pause) {
       pause = false;
       mWaitCondition->wakeAll();
   }
}
 
Корректно ли это (и почему)?
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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