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

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

Страниц: 1 2 [3] 4 5 ... 8   Вниз
  Печать  
Автор Тема: Использование QWaitCondition  (Прочитано 74747 раз)
Bepec
Гость
« Ответ #30 : Декабрь 20, 2012, 12:04 »

На мой взгляд всё нормально. счётчик увеличивается и уменьшается после wait. Т.е. если поток получил задачу и начал её выполнение он прибавляет счётчик. Как выполнит - уменьшает.

Выйти в  == 0 воркеры не могут. ибо в любой момент обработки count будет > 0.

Хотя если возникнет непредвиденное, может полететь всё.

PS и где пропуск?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #31 : Декабрь 20, 2012, 12:29 »

Выйти в  == 0 воркеры не могут. ибо в любой момент обработки count будет > 0.
Не в любой момент кода воркера
PS и где пропуск?
Ищите, ошибка та же самая - полагается что каждый wake будит
Записан
Bepec
Гость
« Ответ #32 : Декабрь 20, 2012, 13:17 »

В упор не вижу.

Там предполагается, что все потоки окончили обработку и застряли на wait.
Если потоки не окончили обработку, count будет > 0. Значит пробуждения не будет до окончания обработки. Нет?

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

Сообщений: 11445


Просмотр профиля
« Ответ #33 : Декабрь 20, 2012, 16:20 »

В упор не вижу.
Здесь надо чуть по-другому смотреть. Берете какое-то место в коде и говорите себе типа "пусть нитка заснула здесь" (ну забрал к нее ОС управление). Потом говорите "а в это время в замке..". Т.е. чем заняты др нитки? Как они могут нагадить? (обычно могут).

Если не дотумкаете - завтра скажу правильный (на мой взгляд) ответ.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #34 : Декабрь 20, 2012, 19:04 »

Ну есть ошибка если пользователь успеет нажать кнопочку и вейкнуть, пока рабочий тред будет проходить между последним анлоком и первым локом.
Записан
Bepec
Гость
« Ответ #35 : Декабрь 20, 2012, 20:46 »

Пользователь не может нажать кнопку, ибо в этот момент проходит цикл while  до последнего занятого потока. От этого и защищает счётчик.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #36 : Декабрь 20, 2012, 21:32 »

Еще раз - счетчик в 0. Рабочий поток стоит ПЕРЕД первым локом (ну не дали ему ни кванта времени). Юзер жмет кнопку. Цикл while скипается (никто еще даже не начинал работать) потоки вейкаются (а еще никто и не ждёт), и только после этого рабочий тред локает мьютекс и встает на вейт.
Ситуация маловероятна, но возможна.
Записан
Bepec
Гость
« Ответ #37 : Декабрь 20, 2012, 21:59 »

Код:
mutex.lock();
     keyPressed.wait(&mutex);
// вот тут поток ждёт.
// Как только происходит wake, mutex захватывается.
     ++count;
// count инкрементируется
     mutex.unlock();
// анлок для действий

Как он может пробудиться без захвата мутекса? Никак.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #38 : Декабрь 20, 2012, 22:07 »

3й раз - рабочий поток ВООБЩЕ ничего не успел сделать. Никто ничего не локал еще.

Код:
// thread worker
     forever { // мы вот тут стоим
     mutex.lock();
     keyPressed.wait(&mutex);
     ++count;
Записан
Bepec
Гость
« Ответ #39 : Декабрь 21, 2012, 07:00 »

Пока count не будет равным 0, контролирующий поток не даст пользователю щелкнуть кнопку.

Цитировать
3й раз - рабочий поток ВООБЩЕ ничего не успел сделать. Никто ничего не локал еще.

Это как? Как может быть такая ситуация? Поток ничего не успел сделать? А мб он ещё и не создан?

Думаю это притянуто за уши к пяткам. Ибо это уже вопрос проектирования. Потоки воркеры должны быть созданы и запущены раньше контрольного. Так же они уже все после запуска будут в wait. После чего начинается цикл аля кто быстрее, и не зря же им даётся целая мс на их работу.

PS можно и по указателю обратиться перед его инициацией. Такая же ошибка будет, помоему.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #40 : Декабрь 21, 2012, 07:45 »

и не зря же им даётся целая мс на их работу.
Вообще-то целая секунда)
Записан

Qt 5.11/4.8.7 (X11/Win)
Bepec
Гость
« Ответ #41 : Декабрь 21, 2012, 07:48 »

Ох ты ж. Спутал с Sleep.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #42 : Декабрь 21, 2012, 11:56 »

пока рабочий тред будет проходить между последним анлоком и первым локом.
Ну вот, это др дело. Можете (если хотите). Только с чего Вы взяли что это "только в первый раз"? Forever крутит любое число раз, и этот участок кода выполняется каждый раз  И насчет "маловероятно" Вы загнули, это еще как вероятно. Разжуем подробно

Код
C++ (Qt)
// thread worker
    forever {
// <--- нитка сейчас здесь
    mutex.lock();
    keyPressed.wait(&mutex);
    ++count;
    mutex.unlock();
 
    do_something();
 
    mutex.lock();
    --count;
    mutex.unlock();
}
 
Перед первым (в коде) локом мутекс свободен, и count == 0. Теперь смотрим что с др ниткой

Код
C++ (Qt)
//control thread
    forever {
    getchar();
 
    mutex.lock();
    // Sleep until there are no busy worker threads
    while (count > 0) {
        mutex.unlock();
        sleep(1);
<--- а эта нитка сейчас здесь
        mutex.lock();
    }
    keyPressed.wakeAll();
    mutex.unlock();
}
 
Она просыпается, захватывает лок, выходит из while (ведь count == 0), и (веселая, счастливая) вызывает wakeAll (кстати тоже неправильно, но об этом позже). Но на мутексе никто не ждет. Итог - "производитель произвел", а вот "потребитель" - ничего не "потребил". Более того, если производитель шустрый - он может напроизводить много чего - и все будет утеряно.

Думаю это притянуто за уши к пяткам. Ибо это уже вопрос проектирования. Потоки воркеры должны быть созданы и запущены раньше контрольного. Так же они уже все после запуска будут в wait.
Такого рода проектирование должно быть признано неполноценным и не заслуживающим обсуждения. Делая какие-то предположения о скорости выполнения Вы тем самым расписываетесь в том что сделать "просто корректно/нормально" Вы не можете. Зачем оно Вам надо? Ведь сделать правильно проще и лучше

А остальное - критикуем, опровергаем   Улыбающийся
Записан
Bepec
Гость
« Ответ #43 : Декабрь 21, 2012, 12:18 »

Помоему тут некая другая ситуация.

На мой взгляд имеется как раз модель нормального поведения - если поток готов работать, он сработает. Если нет - он не будет задействован (мало ли что с ним).

И мне кажется, что данный пример демонстрирует не "по нажатию кнопки работа N потоков", а "по нажатия кнопки работа свободных/готовых к обработке потоков".

PS во всяком случае упоминания о том, что этот пример будет всегда вызывать N потоков я нигде не видел.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #44 : Декабрь 21, 2012, 12:46 »

Помоему тут некая другая ситуация.
Типичный малосодержательный пост по принципу "думать лень, напишу-ка что-нибудь, авось сойдет"  Улыбающийся
Разговор о том что даже если всего 2 нитки (производитель и потребитель), запущенные в каком угодно порядке и уже отработавшие любое время - все равно "пакеты теряются", потреблено меньше чем произведено.
Записан
Страниц: 1 2 [3] 4 5 ... 8   Вверх
  Печать  
 
Перейти в:  


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