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

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

Страниц: 1 [2] 3 4 ... 8   Вниз
  Печать  
Автор Тема: Использование QWaitCondition  (Прочитано 74674 раз)
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


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

Кстати, помнится мне, что уже было на форуме аналогичное обсуждение.

Записан

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

Сообщений: 11445


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

to Igors:
Но ведь wakeAll тогда в любом случае может "пропустить" цикл. Как от этого избавиться?

PS в любом случае, я так понимаю, если в ожидающем цикле будут действия после unlock, это приведёт как раз к возможному пропуску wakeAll(). так ведь?

update:
В том то всё и дело, что в любом случае после unlock у нас получается участок времени (пусть пренебрежительно малый, но всё же), во время которого наш wakeAll умрёт и в очереди останется необработанная часть данных.

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

Бояться пропуска wake не следует, в этом случае нас спасает счетчик данных. Если данные уже есть - извлекаем и обрабатываем, и только если нет - вызываем wait. Отсюда следует что WaitCondition ВСЕГДА используется со счетчиком, без него вся схема разваливается

Ладно, а слабо найти пробой в ассыстенте? (пример QWaitCondition)
Записан
Bepec
Гость
« Ответ #17 : Декабрь 18, 2012, 20:50 »

Хвалить полезно, принимать хвалу опасно Улыбающийся

Попробую разобраться завтра.

А так конечно да. Счётчик vs Wait на взгляд помогают решить эту проблему. Надо самому попробовать.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


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

Я конечно понимаю, что обсирать кутешную доку - любимое дело Igors'а, но, если бы кто-то удосужился в нее заглянуть, то сразу после некорректного примера написано
Цитировать
Also, if some of the threads are still in do_something() when the key is pressed, they won't be woken up (since they're not waiting on the condition variable) and so the task will not be performed for that key press. This issue can be solved using a counter and a QMutex to guard it.
После чего идёт пример со счётчиком (в него уже не вникал, ибо лень; но факт в том, что он есть).
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

Я конечно понимаю, что обсирать кутешную доку - любимое дело Igors'а, но, если бы кто-то удосужился в нее заглянуть,
Аккуратнее пожалуйста, грубость и высокомерие Вас не украшают

После чего идёт пример со счётчиком (в него уже не вникал, ибо лень; но факт в том, что он есть).
О нем и речь
Записан
Bepec
Гость
« Ответ #20 : Декабрь 19, 2012, 12:50 »

Пожалуй меня в недоумение ввёл сон на 1 мс. Да и вызов wakeAll с залоченным мутексом.

А так - вроде нормально.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

Пожалуй меня в недоумение ввёл сон на 1 мс. Да и вызов wakeAll с залоченным мутексом.

А так - вроде нормально.
Давайте для начала Вы приведете полный текст примера чтобы всем было однозначно ясно о чем речь. 
Записан
Bepec
Гость
« Ответ #22 : Декабрь 19, 2012, 13:23 »

Код:
// thread worker
     forever {
     mutex.lock();
     keyPressed.wait(&mutex);
     ++count;
     mutex.unlock();

     do_something();

     mutex.lock();
     --count;
     mutex.unlock();
 }

//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();
 }
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


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

Аккуратнее пожалуйста, грубость и высокомерие Вас не украшают

Да нет, просто я регулярно (а точнее только их) вижу посты, содерщащие слова "писать по букварю", "обезьянки в ассистанте". Напрягает, если честно.

Тема хорошая и полезная (благодаря ей нашел у себя багу), однако постановка раздражает.
Записан
Bepec
Гость
« Ответ #24 : Декабрь 19, 2012, 13:44 »

По теме, господа, по теме.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

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

На мой взгляд, беда в том что Qt букварь... слишком хорош, и это плохо (как бы "крайности сходятся"). Люди получают готовые, 100% разжеванные решения и.. моментально к этому привыкают. Какая там "удочка" если вокруг полным-полно вкуснейшей, жирнючей "рыбы" - хватило бы сил сожрать. Или не так?  Улыбающийся

Тема хорошая и полезная (благодаря ей нашел у себя багу), однако постановка раздражает.
Ничего, переживете. А лучше подключайтесь-ка к изучению примера (см ниже) - там есть о чем поговорить, мне тоже далеко не все ясно/однозначно

----------

Верес, спасибо за copy/paste (ну просто здесь так надо). С чего начнем? Почему нужен sleep? Или где должен быть wake (внутри или снаружи захвата мутекса). Или где еще ошибка? Керуйте  Улыбающийся
Записан
Bepec
Гость
« Ответ #26 : Декабрь 19, 2012, 14:50 »

Зачем нужен слип в принципе понятно.
Непонятно зачем блочить мутекс каждый раз в while. И эти постоянные локи унлоки настораживают. (и помоему они подтормаживать должны?)

По видимому вполне возможна ситуация deadlock'a (или меня вводит в заблуждение отсутствие условия вызовов)
Код:
 while (count > 0) {
// тут     
         mutex.unlock();
         sleep(1);
         mutex.lock();
// тут
     }

Хотя если потумкать и если вызываются слоты в разных потоках, тогда код на вид нормальный.

Код:
// thread worker
     forever {
     mutex.lock();
     keyPressed.wait(&mutex);     //ждём wake
     ++count;
     mutex.unlock();

     do_something();

     mutex.lock();
     --count;
     mutex.unlock();
 }
                                             
//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();                   // а тут уже даём им старт
     }
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

Зачем нужен слип в принципе понятно.
Непонятно зачем блочить мутекс каждый раз в while. И эти постоянные локи унлоки настораживают. (и помоему они подтормаживать должны?)

По видимому вполне возможна ситуация deadlock'a (или меня вводит в заблуждение отсутствие условия вызовов)
Код:
 while (count > 0) {
// тут     
         mutex.unlock();
         sleep(1);
         mutex.lock();
// тут
     }
Подтормаживать еще как должны - а что делать? Ведь здесь очереди-то нет (контейнера), приходится ждать пока обработчик "просрется" (навеяно предыдущим докладчиком). А просто так сделать sleep не катит - ведь мутекс захвачен нами, и обработчик не сработает до тех пор пока не освободим. Приходится сначала освобождать, ждать, потом опять захватывать. Вообще ихний пример как бы "наоборот" - показывает не силу а слабость примитива WaitCondition (ну вот, меня опять обвинят в нелояльности). Но базовый примитив на то и базовый - работать должно. Deadlock - откуда? Я захватил мутекс, я и освобождаю, никаких условий не использую 

Хотя если потумкать и если вызываются слоты в разных потоках, тогда код на вид нормальный.
"One thing at a time" как говорят буржуины. Или, по-нашему, "не гоните лошадей". Вот если все ясно почему sleep - тогда поехали дальше.
Записан
Bepec
Гость
« Ответ #28 : Декабрь 19, 2012, 15:55 »

Деадлок будет, если управляющий и работающий потоки окажутся в одной нити.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

Ладно, пошли дальше.
Код:
// thread worker
     forever {
     mutex.lock();
     keyPressed.wait(&mutex);     //ждём wake
     ++count;
...
Да, счетчик вроде есть, но он используется уже после wait. Это не может работать правильно, в какой-то момент цикл обработки будет пропущен. Укажите как это происходит - или докажите что такое невозможно (и я не прав)
Записан
Страниц: 1 [2] 3 4 ... 8   Вверх
  Печать  
 
Перейти в:  


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