Название: Использование QWaitCondition Отправлено: Igors от Декабрь 17, 2012, 22:30 Добрый день
На мой взгляд, QWaitCondition - вещь хитрая, и надеяться на то что "прочитал ассистент и сделал по образцу" не приходится. Часто слышно "используй QWaitCondition", но доходит до дела - и никто не знает как :) Ну так почему бы нам это не перетереть и не углУбить свои знания/понимание? Есть задачки на QWaitCondition - постите сюда, обсудим. Начнем с простого: вот пример неправильного использования. Я специально не привожу автора - все ошибаются, но дело не в том кто ошибся, а как правильно Цитировать т.е. строго по доке: Ну насчет "строго по доке" - верить необязательно :)поток 1: захват мутекса wait отпускаем мьютекс поток 2: wake Да, и не надо спрашивать "а в чем вопрос?" - не каждый пост должен быть вопросом :) Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 17, 2012, 23:16 Кхм. Мини вопрос - а что там неправильного?
Возможно моих знаний не хватает. Возможно мой проект на неправильном использовании сделан и работает. Так в чём? Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 18, 2012, 10:27 Кхм. Мини вопрос - а что там неправильного? Этот псевдокод не ведет к крашу и "при каком-то стечении обстоятельств" может быть работоспособным. Он просто наивен. Вызывая wakeOne/wakeAll из нитки 2 мы почему-то считаем, что нитка 1 ждет на QWaitCondition. Если это так - все норм. Однако если нитка 2 по каким-то причинам не успела встать на wait - все рушится. wake не имеет эффекта т.к. нет ожидающих на мутексе. И когда позже нитка 2 пришла на wait - ее уже некому разбудить. Возможно мой проект на неправильном использовании сделан и работает. Предъявляем псевдокод или упрощенный проект (Вам виднее) - посмотрим, пощупаемНазвание: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 18, 2012, 13:37 вырезанный код
Код: /* Поток запущен, ждёт поступления данных. Другие потоки читают/генерируют данные, вызывают функцию addTurn. Поток просыпается, обрабатывает данные до конца очереди и опять засыпает. Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 18, 2012, 14:14 вырезанный код После выхода из wait.wait мутекс захвачен этой ниткой, поэтому уточните где Вы его освобождаете в run. Лучше исправьте/дополните Ваш пост, т.к. двоечтение и/или оговорку на словах обсуждать будет трудноКод: void run Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 18, 2012, 15:32 Добавил в моё сообщение выше вырезку.
Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 18, 2012, 16:39 Ладно, давайте я распишу с комментариями
Код Ваш код имеет 2 помарки - не нужно делать wait если задачи в очереди есть, так некоторые задачи могут долго стоять в очереди если она не пополняется - как только мутекс освобожден Вы не должны трогать turn до след захвата Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 18, 2012, 16:55 Эм?
1) Если задачи в очереди есть? Это как? Этот код начинает выполняться в момент запуска потока. Потому де факто у него нет данных. В дальнейшем wait будет ждать до тех пор, пока не появятся данные. Когда появятся данные, все они будут обработаны, т.е. при следующей проходке цикла у нас опять получается отсутствие данных. И если же сделать проверку, то я думаю, можно вполне попасть в ситуацию, когда 1 поток будет добавлять данные, а поток тут же их обрабатывать, не оставляя возможности другим потокам. (смутно, но думаю смысл донёс). 2) Расписываю. Получаю мутекс, получаю размер полученных данных. Отпускаю мутекс. Далее циклично вызывается слот createResultString(getTurn()). getTurn() имеет в своем теле конструкция аля Код: lock.lock(); имеют ли ваши помарки обоснования, при этой добавочной информации? Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 18, 2012, 17:39 имеют ли ваши помарки обоснования, при этой добавочной информации? Да, имеют, правда помарки не мои а Ваши :) Давайте по порядочку 1) В жизни это происходит по-другому. Какое-то число wakeAll "съедается" т.к. нет ожидающих на мутексе. напрЕсли задачи в очереди есть? Это как? Этот код начинает выполняться в момент запуска потока. Потому де факто у него нет данных. В дальнейшем wait будет ждать до тех пор, пока не появятся данные. Когда появятся данные, все они будут обработаны, т.е. при следующей проходке цикла у нас опять получается отсутствие данных. Код: lock.unlock(); Не спешите, здесь лучше разобраться капитально, вещь непростая Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 18, 2012, 17:56 И вправду слабое место тут есть, но к счастью не в моём проекте :D Имеется нитка, генерирующая постоянные события и данная технология используется для логгирования :)
А так да, вы правы. И каково же решение этой проблемы? Не отпускать мутекс, пока не будет обработано всё ? (или помещено в отдельный контейнер?) не будет ли это затратнее чем постоянно генерящиеся события? Название: Re: Использование QWaitCondition Отправлено: kuzulis от Декабрь 18, 2012, 18:18 Скорее всего не делать wakeAll :), а будить только те потоки, которые в этом нуждаются, не?
И вообще, какая используется "архитектура"? Один производитель и много потребителей? Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 18, 2012, 18:20 И каково же решение этой проблемы? Не отпускать мутекс, пока не будет обработано всё ? Это плохо т.к. заставляет подающие нитки ждать конца обработки (или помещено в отдельный контейнер?) не будет ли это затратнее чем постоянно генерящиеся события? Реально очередь почти всегда - контейнер указателей на задачи, затраты на их перемещение пренебрежимо малы по сравнению с обработкой. В Qt может быть и не указатель, но с имплисит шарой тоже быстро. Вообще про временный контейнер я упомянул для полноты картины. Обработка "пачками" возможна, но встречается редко, действовать "по одному" проще, а тогда достаточно просто Код
Название: Re: Использование QWaitCondition Отправлено: kuzulis от Декабрь 18, 2012, 18:28 Код
А чем это в принципе отличается от: Код
? В чем прикол то? Если for(i = 0...) тоже быстро выполнится, считаем, что затрат нет. Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 18, 2012, 18:31 Скорее всего не делать wakeAll :), а будить только те потоки, которые в этом нуждаются, не? Сильная сторона WaitCondition как раз в том что будиться будут спящие, а уже работающим та побудка пофиг И вообще, какая используется "архитектура"? Один производитель и много потребителей? Та откуда я знаю? Учил транзисторы и даже лампы (1 семестр), яка там "архитектура"В чем прикол то? Если for(i = 0...) тоже быстро выполнится, считаем, что затрат нет. Нет никакого прикола - просто хочу по-одному, а могу и пачками (разные варианты, суть одна)Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 18, 2012, 18:32 Много производителей и один потребитель :) Производители - потоки, генерящие данные. Потребитель - один этот поток, преобразующий в необходимую форму лог.
В моём случае несущественно. to Igors: Но ведь wakeAll тогда в любом случае может "пропустить" цикл. Как от этого избавиться? PS в любом случае, я так понимаю, если в ожидающем цикле будут действия после unlock, это приведёт как раз к возможному пропуску wakeAll(). так ведь? update: В том то всё и дело, что в любом случае после unlock у нас получается участок времени (пусть пренебрежительно малый, но всё же), во время которого наш wakeAll умрёт и в очереди останется необработанная часть данных. И даже несколько потоков не дадут 100% гарантии в покрытии этого места. Название: Re: Использование QWaitCondition Отправлено: kuzulis от Декабрь 18, 2012, 18:41 Кстати, помнится мне, что уже было на форуме аналогичное обсуждение (http://www.prog.org.ru/topic_21460_0.html).
Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 18, 2012, 18:51 to Igors: Ну что сказать - молодец, думает пацан, а не так себе, букварь всасывает (ой перехвалю :))Но ведь wakeAll тогда в любом случае может "пропустить" цикл. Как от этого избавиться? PS в любом случае, я так понимаю, если в ожидающем цикле будут действия после unlock, это приведёт как раз к возможному пропуску wakeAll(). так ведь? update: В том то всё и дело, что в любом случае после unlock у нас получается участок времени (пусть пренебрежительно малый, но всё же), во время которого наш wakeAll умрёт и в очереди останется необработанная часть данных. И даже несколько потоков не дадут 100% гарантии в покрытии этого места. Бояться пропуска wake не следует, в этом случае нас спасает счетчик данных. Если данные уже есть - извлекаем и обрабатываем, и только если нет - вызываем wait. Отсюда следует что WaitCondition ВСЕГДА используется со счетчиком, без него вся схема разваливается Ладно, а слабо найти пробой в ассыстенте? (пример QWaitCondition) Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 18, 2012, 20:50 Хвалить полезно, принимать хвалу опасно :)
Попробую разобраться завтра. А так конечно да. Счётчик vs Wait на взгляд помогают решить эту проблему. Надо самому попробовать. Название: Re: Использование QWaitCondition Отправлено: Авварон от Декабрь 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. После чего идёт пример со счётчиком (в него уже не вникал, ибо лень; но факт в том, что он есть).Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 19, 2012, 12:37 Я конечно понимаю, что обсирать кутешную доку - любимое дело Igors'а, но, если бы кто-то удосужился в нее заглянуть, Аккуратнее пожалуйста, грубость и высокомерие Вас не украшаютПосле чего идёт пример со счётчиком (в него уже не вникал, ибо лень; но факт в том, что он есть). О нем и речьНазвание: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 19, 2012, 12:50 Пожалуй меня в недоумение ввёл сон на 1 мс. Да и вызов wakeAll с залоченным мутексом.
А так - вроде нормально. Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 19, 2012, 13:01 Пожалуй меня в недоумение ввёл сон на 1 мс. Да и вызов wakeAll с залоченным мутексом. Давайте для начала Вы приведете полный текст примера чтобы всем было однозначно ясно о чем речь. А так - вроде нормально. Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 19, 2012, 13:23 Код: // thread worker Название: Re: Использование QWaitCondition Отправлено: Авварон от Декабрь 19, 2012, 13:43 Аккуратнее пожалуйста, грубость и высокомерие Вас не украшают Да нет, просто я регулярно (а точнее только их) вижу посты, содерщащие слова "писать по букварю", "обезьянки в ассистанте". Напрягает, если честно. Тема хорошая и полезная (благодаря ей нашел у себя багу), однако постановка раздражает. Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 19, 2012, 13:44 По теме, господа, по теме.
Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 19, 2012, 14:34 Да нет, просто я регулярно (а точнее только их) вижу посты, содерщащие слова "писать по букварю", "обезьянки в ассистанте". Напрягает, если честно. Насчет "обезьянок" - покажите где я такое допустил, извинюсь немедленно. Мне легко говорить - потому что не было такого :) "Букварь" - да, я говорю это часто, и что в этом плохого? Это базовая документация которую надо учить - в любой системе. Да, сначала надо "сделать по букварю" - может и проблем не возникнет. На мой взгляд, беда в том что Qt букварь... слишком хорош, и это плохо (как бы "крайности сходятся"). Люди получают готовые, 100% разжеванные решения и.. моментально к этому привыкают. Какая там "удочка" если вокруг полным-полно вкуснейшей, жирнючей "рыбы" - хватило бы сил сожрать. Или не так? :) Тема хорошая и полезная (благодаря ей нашел у себя багу), однако постановка раздражает. Ничего, переживете. А лучше подключайтесь-ка к изучению примера (см ниже) - там есть о чем поговорить, мне тоже далеко не все ясно/однозначно---------- Верес, спасибо за copy/paste (ну просто здесь так надо). С чего начнем? Почему нужен sleep? Или где должен быть wake (внутри или снаружи захвата мутекса). Или где еще ошибка? Керуйте :) Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 19, 2012, 14:50 Зачем нужен слип в принципе понятно.
Непонятно зачем блочить мутекс каждый раз в while. И эти постоянные локи унлоки настораживают. (и помоему они подтормаживать должны?) По видимому вполне возможна ситуация deadlock'a (или меня вводит в заблуждение отсутствие условия вызовов) Код: while (count > 0) { Хотя если потумкать и если вызываются слоты в разных потоках, тогда код на вид нормальный. Код: // thread worker Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 19, 2012, 15:38 Зачем нужен слип в принципе понятно. Подтормаживать еще как должны - а что делать? Ведь здесь очереди-то нет (контейнера), приходится ждать пока обработчик "просрется" (навеяно предыдущим докладчиком). А просто так сделать sleep не катит - ведь мутекс захвачен нами, и обработчик не сработает до тех пор пока не освободим. Приходится сначала освобождать, ждать, потом опять захватывать. Вообще ихний пример как бы "наоборот" - показывает не силу а слабость примитива WaitCondition (ну вот, меня опять обвинят в нелояльности). Но базовый примитив на то и базовый - работать должно. Deadlock - откуда? Я захватил мутекс, я и освобождаю, никаких условий не использую Непонятно зачем блочить мутекс каждый раз в while. И эти постоянные локи унлоки настораживают. (и помоему они подтормаживать должны?) По видимому вполне возможна ситуация deadlock'a (или меня вводит в заблуждение отсутствие условия вызовов) Код: while (count > 0) { Хотя если потумкать и если вызываются слоты в разных потоках, тогда код на вид нормальный. "One thing at a time" как говорят буржуины. Или, по-нашему, "не гоните лошадей". Вот если все ясно почему sleep - тогда поехали дальше. Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 19, 2012, 15:55 Деадлок будет, если управляющий и работающий потоки окажутся в одной нити.
Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 20, 2012, 09:03 Ладно, пошли дальше.
Код: // thread worker Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 20, 2012, 12:04 На мой взгляд всё нормально. счётчик увеличивается и уменьшается после wait. Т.е. если поток получил задачу и начал её выполнение он прибавляет счётчик. Как выполнит - уменьшает.
Выйти в == 0 воркеры не могут. ибо в любой момент обработки count будет > 0. Хотя если возникнет непредвиденное, может полететь всё. PS и где пропуск? Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 20, 2012, 12:29 Выйти в == 0 воркеры не могут. ибо в любой момент обработки count будет > 0. Не в любой момент кода воркераPS и где пропуск? Ищите, ошибка та же самая - полагается что каждый wake будит Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 20, 2012, 13:17 В упор не вижу.
Там предполагается, что все потоки окончили обработку и застряли на wait. Если потоки не окончили обработку, count будет > 0. Значит пробуждения не будет до окончания обработки. Нет? Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 20, 2012, 16:20 В упор не вижу. Здесь надо чуть по-другому смотреть. Берете какое-то место в коде и говорите себе типа "пусть нитка заснула здесь" (ну забрал к нее ОС управление). Потом говорите "а в это время в замке..". Т.е. чем заняты др нитки? Как они могут нагадить? (обычно могут). Если не дотумкаете - завтра скажу правильный (на мой взгляд) ответ. Название: Re: Использование QWaitCondition Отправлено: Авварон от Декабрь 20, 2012, 19:04 Ну есть ошибка если пользователь успеет нажать кнопочку и вейкнуть, пока рабочий тред будет проходить между последним анлоком и первым локом.
Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 20, 2012, 20:46 Пользователь не может нажать кнопку, ибо в этот момент проходит цикл while до последнего занятого потока. От этого и защищает счётчик.
Название: Re: Использование QWaitCondition Отправлено: Авварон от Декабрь 20, 2012, 21:32 Еще раз - счетчик в 0. Рабочий поток стоит ПЕРЕД первым локом (ну не дали ему ни кванта времени). Юзер жмет кнопку. Цикл while скипается (никто еще даже не начинал работать) потоки вейкаются (а еще никто и не ждёт), и только после этого рабочий тред локает мьютекс и встает на вейт.
Ситуация маловероятна, но возможна. Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 20, 2012, 21:59 Код: mutex.lock(); Как он может пробудиться без захвата мутекса? Никак. Название: Re: Использование QWaitCondition Отправлено: Авварон от Декабрь 20, 2012, 22:07 3й раз - рабочий поток ВООБЩЕ ничего не успел сделать. Никто ничего не локал еще.
Код: // thread worker Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 21, 2012, 07:00 Пока count не будет равным 0, контролирующий поток не даст пользователю щелкнуть кнопку.
Цитировать 3й раз - рабочий поток ВООБЩЕ ничего не успел сделать. Никто ничего не локал еще. Это как? Как может быть такая ситуация? Поток ничего не успел сделать? А мб он ещё и не создан? Думаю это притянуто за уши к пяткам. Ибо это уже вопрос проектирования. Потоки воркеры должны быть созданы и запущены раньше контрольного. Так же они уже все после запуска будут в wait. После чего начинается цикл аля кто быстрее, и не зря же им даётся целая мс на их работу. PS можно и по указателю обратиться перед его инициацией. Такая же ошибка будет, помоему. Название: Re: Использование QWaitCondition Отправлено: GreatSnake от Декабрь 21, 2012, 07:45 и не зря же им даётся целая мс на их работу. Вообще-то целая секунда)Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 21, 2012, 07:48 Ох ты ж. Спутал с Sleep.
Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 21, 2012, 11:56 пока рабочий тред будет проходить между последним анлоком и первым локом. Ну вот, это др дело. Можете (если хотите). Только с чего Вы взяли что это "только в первый раз"? Forever крутит любое число раз, и этот участок кода выполняется каждый раз И насчет "маловероятно" Вы загнули, это еще как вероятно. Разжуем подробно Код Перед первым (в коде) локом мутекс свободен, и count == 0. Теперь смотрим что с др ниткой Код Она просыпается, захватывает лок, выходит из while (ведь count == 0), и (веселая, счастливая) вызывает wakeAll (кстати тоже неправильно, но об этом позже). Но на мутексе никто не ждет. Итог - "производитель произвел", а вот "потребитель" - ничего не "потребил". Более того, если производитель шустрый - он может напроизводить много чего - и все будет утеряно. Думаю это притянуто за уши к пяткам. Ибо это уже вопрос проектирования. Потоки воркеры должны быть созданы и запущены раньше контрольного. Так же они уже все после запуска будут в wait. Такого рода проектирование должно быть признано неполноценным и не заслуживающим обсуждения. Делая какие-то предположения о скорости выполнения Вы тем самым расписываетесь в том что сделать "просто корректно/нормально" Вы не можете. Зачем оно Вам надо? Ведь сделать правильно проще и лучшеА остальное - критикуем, опровергаем :) Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 21, 2012, 12:18 Помоему тут некая другая ситуация.
На мой взгляд имеется как раз модель нормального поведения - если поток готов работать, он сработает. Если нет - он не будет задействован (мало ли что с ним). И мне кажется, что данный пример демонстрирует не "по нажатию кнопки работа N потоков", а "по нажатия кнопки работа свободных/готовых к обработке потоков". PS во всяком случае упоминания о том, что этот пример будет всегда вызывать N потоков я нигде не видел. Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 21, 2012, 12:46 Помоему тут некая другая ситуация. Типичный малосодержательный пост по принципу "думать лень, напишу-ка что-нибудь, авось сойдет" :)Разговор о том что даже если всего 2 нитки (производитель и потребитель), запущенные в каком угодно порядке и уже отработавшие любое время - все равно "пакеты теряются", потреблено меньше чем произведено. Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 21, 2012, 14:05 Не надо называть мои посты малосодержательными. Я обижаюсь.
Затестил 2000 запусков управляющего потока. Проанализировал файл логов. Результат: Код: count 7988 error 0 tmpA () Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 21, 2012, 14:32 Затестил 2000 запусков управляющего потока. Проанализировал файл логов. Результат: Как говорили классики Цитировать Тестирование может показать наличие ошибок но не их отсутствие Тем более что в данном случае тестирование затруднительно. Можно действовать гораздо проще.Код: mutex.lock(); Так, ну и чего ждем? Изменяем пример чтобы было правильно :) Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 21, 2012, 14:45 А в любом случае где нибудь пробой да произойдёт, насколько я понимаю.
Идеальный в вашем понимании код как должен выглядеть? Wait с счётчиком больше 0? А смысл? Ведь инкремент идёт после пробуждения. До него wait будет бесконечным. Смысл то в том, что счётчик сигнализирует управляющему, что рабочие заняты. Чуть поясню для себя же. Рабочий поток Код: //Создаём воркеры и управляющий В данном примере count не является счётчиком необходимых для выполнения задач. А является счётчиком работающих потоков. PS я неправ? Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 21, 2012, 19:50 А в любом случае где нибудь пробой да произойдёт, насколько я понимаю. Не хочу "размазывать цитаты", отвечу как бы пунктамиИдеальный в вашем понимании код как должен выглядеть? Wait с счётчиком больше 0? А смысл? Ведь инкремент идёт после пробуждения. До него wait будет бесконечным. - верно, если нет опоры на счетчик, все равно пробьет - схема WaitCondition одна и та же для потребителя (т.е. принимающего задачи). Называть ее идеальной нет смысла, другой просто нет. Я ее расписывал выше, просто повторяйте ее (конечно подставляя данные/переменные задачи). Возможно Вас сбило с толку что в первой редакции своего предыдущего поста я перепутал слова нулевой/ненулевой (ну зарапортовался, бывает :)) - "инкремент идет после пробуждения" - а почему это воспринимается как абсолютная истина? Только потому что так написано в букваре? Так возможны ошибки и там (пусть редко). Покажите творческий (а не механический) подход Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 21, 2012, 19:54 Кхм. Пошла уже демагогия по "абсолютную истину".
- Опора на счётчик не может быть в данном примере. Ибо он сделан с "необязательным" исполнением всех потоков. - Угум. Приведите код схемы пожалуйста. Копать тему мне (да и другим) не особо хочется. - Мы как бы разбирали пример. В данном примере инкремент в другом месте бессмысленен. Как бы выйти из этой ситуации? Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 21, 2012, 21:20 Кхм. Пошла уже ... Ваш ответ поразительно напоминает другого молодого человека (ну Вы помните), опять-таки куча всяких причин, а 20 (максимум) строк кода - не дождетесь! Чего выкручиваться - ведь "шила в мешке не утаишь" :)Никогда не надо бояться сказать "да, сейчас я не могу этого сделать - ну не знаю как". Вот последние 2 недели я застрял с adaptive deep shadow sampling - да, ну не знаю как, ищу. Поиск решения - нормальное состояние программиста, остальное извращения. Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 22, 2012, 01:24 Эмм.. помоему тут как раз поговорка про бревно в своём глазу подойдёт :)
Вы предлагаете исправить данный пример, а кода от вас не дождёшься :D Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 22, 2012, 12:19 Вы предлагаете исправить данный пример, а кода от вас не дождёшься :D Ага, "вот предложил - сам и исправляй" :) Ладно, подождем пару деньков, может найдутся смелыеНазвание: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 22, 2012, 14:09 Я всё таки не вижу смысла в этом "исправлении". То, что вы предлагаете разительно отличается от текущего примера. То не исправление будет, а вообще другой подход и новый пример.
Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 24, 2012, 10:35 Причешем исходный пример
Код
Код Оба (HandleTask и CreateTask) могут быть сколь угодно сложными, могут освобождать мутекс и опять захватывать, использовать общие переменные (count) и.т.п. Но с точки зрения QWaitCondition нам совершенно не нужно вникать во все их подробности. Просто добавляем счетчик Код
Код Нашего героя смутила переменная с именем "count", он подумал что это тот самый счетчик что и должен использоваться QWaitCondition. В действительности же "в огороде бузина, а в Киеве дядька" :) Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 24, 2012, 10:55 Кхм. У вас не "причёсанный" пример.
Вы вырезали проверку на наличие работающих потоков. И в вашем случае работать будет только 1 поток. Проще выражаясь вы убили многопоточность, у вас 1 производитель, 1 потребитель, и радуетесь этому? Если непонятно, то в один момент времени у вас будет выполняться лишь 1 воркер. Многопоточность убита. Подвожу краткую выжимку: Что сделал Igors: Удалил проверку на наличие работающих потоков. Убил многопоточность. Что получилось: Получился один воркер и ненужный контрольный поток. Ненужный потому, что с таким же успехом от него можно отказаться и функционал не изменится. PS я вот одного не пойму, зачем вы убили многопоточность? Или я чего то не вижу и воркеры могут выполнять HandleTask параллельно? Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 24, 2012, 11:01 PS я вот одного не пойму, зачем вы убили многопоточность? Или я чего то не вижу и воркеры могут выполнять HandleTask параллельно? Конечно могут. Никого я не убивал - просто перенес куски кода в ф-ции HandleTask и CreateTask, все работает как раньше - только теперь задачи не пропускает :) Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 24, 2012, 12:05 Код: // thread worker Как задача может выполняться параллельно, если мутекс может быть заблокирован только одним потоком???? У вас получается последовательное выполнение. Код: //worker 1 А нужно Код: lock-unlock // worker'ы прибавили счётчик, освободили мутекс. В вашем примере нет многопоточного выполнения задачи. Есть простое последовательное выполнение. Мутекс ваш в воркере не даёт им параллельно выполнять задачу. В примере же ассистента происходит параллельное выполнение ёмкой функции. Затраты на мутекс лок/анлок незначительны по сравнению с задачей. Хотя нет, даже не так. Данный подход как раз и нужен для параллельного выполнения ресурсоёмких задач. PS покажите мне параллельность в вашем примере. Как нубу/простачку покажите. Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 24, 2012, 12:15 PS покажите мне параллельность в вашем примере. Код
Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 24, 2012, 13:08 Вах, на виду то всё было, а я ж слепой да не заметил :)
И опять появляется некое count? Или у вас опечаточка с numTask? Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 24, 2012, 13:17 И опять появляется некое count? Или у вас опечаточка с numTask? Он и не исчезал. Просто QWaitCondition нужен др счетчик, я его и добавил (numTask)Название: Re: Использование QWaitCondition Отправлено: Авварон от Декабрь 24, 2012, 14:25 Что-то я всё равно не понял. На просьбу показать параллельность Igors процитировал исходный пример кутешников.
А в его-то исправленном коде где анлок? Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 24, 2012, 14:28 Что-то я всё равно не понял. На просьбу показать параллельность Igors процитировал исходный пример кутешников. Так я же вызываю HandleTask. Никаких новых lock/unlock не было добавленоА в его-то исправленном коде где анлок? Название: Re: Использование QWaitCondition Отправлено: Авварон от Декабрь 24, 2012, 14:43 А, туплю.
Название: Re: Использование QWaitCondition Отправлено: Old от Декабрь 24, 2012, 15:01 Код
Название: Re: Использование QWaitCondition Отправлено: Old от Декабрь 24, 2012, 15:05 В Qt примере можно было запустить 5 воркеров и управляющий поток мог их параллельно запускать.
Сейчас не так. Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 24, 2012, 15:10 Код
В Qt примере можно было запустить 5 воркеров и управляющий поток мог их параллельно запускать. Поясните почемуСейчас не так. Название: Re: Использование QWaitCondition Отправлено: Old от Декабрь 24, 2012, 15:17 Поясните почему Код
Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 24, 2012, 15:39 (не цитирую для экономии места). Да, мы создаем 1 задачу и будим только одну нитку, с этой точки зрения аккуратнее wakeOne. Но никто не мешает увеличить numTask на 2 или больше и тогда уже wakeAll. В любом случае сколько задач создать решает производитель. А в исходном примере некоторые рабочие нитки (потребители) могли остаться непробужденными, а задачи утерянными.
Название: Re: Использование QWaitCondition Отправлено: Dancing_on_water от Декабрь 24, 2012, 15:51 Код: Просто добавляем счетчик И сели в лужу, если потребителей больше создателей. Ситуация: создатель разбудил всех и ушел следующий чар ждать. numTask =1; Просыпается рабочий уменьшает счетчик numTask =0; За ним проспается второй рабочий, обнаруживает, что счетчик нулевой и уходит спать. Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 24, 2012, 16:51 Кстати последнее замечание верно :)
PS Igors добавь свою "очевидную" функцию в то сообщение. А то народ как и я умением видеть невидимое обделены :D Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 24, 2012, 17:16 И сели в лужу, если потребителей больше создателей. Ситуация: создатель разбудил всех и ушел следующий чар ждать. numTask =1; Просыпается рабочий уменьшает счетчик numTask =0; За ним проспается второй рабочий, обнаруживает, что счетчик нулевой и уходит спать. Видимо в азарте меня уличить Вы не увидели мой предыдущий пост :) Да, именно так все и происходит, а чего будить 2 или более рабочих если работа есть только для одного? Дайте больше работ и будите больше работников. Заметим что для каких-то целей такая побудка все же годится (напр проснувшиеся могут проверить флажок abort)PS Igors добавь свою "очевидную" функцию в то сообщение. А то народ как и я умением видеть невидимое обделены :D Вижу - начинаете борзеть, значит пора дать следующую задачу :) Может лучше завтра создать новую тему, а то уже 5 листов, тяжеловато? Или уже все ясно и больше не нужно? :)Название: Re: Использование QWaitCondition Отправлено: Bepec от Декабрь 24, 2012, 17:39 Не "борзеть", а указывать вам на ошибки. Ваша функция, которая нигде в том посте не описана вызывает стойкое желание прекращать разговоры. Ибо когда человек сначала говорит - всё ок, а через несколько часов добавляет - да всё просто, вот я просто не написал функцию - это немного. Невежливо.
И да, у вас опять же пример перекорёжен. Вместо побудки свободных потоков у вас опять таки идёт побудка какого то "определённого" количества. Сможете сделать пример как в ассистенте, только без этого слабого места? Т.е. воркеры и управляющий. Управляющий будит рабочих только после полной их отработки? PS А то получается как в сказке - обещал ему полцарства и коня, а дал палку с надписью полцарства и конь. Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 24, 2012, 17:52 вызывает стойкое желание прекращать разговоры. Хорошо, умолкаю :)Название: Re: Использование QWaitCondition Отправлено: Dancing_on_water от Декабрь 24, 2012, 17:53 Видимо в азарте меня уличить Вы не увидели мой предыдущий пост :) Да, именно так все и происходит, а чего будить 2 или более рабочих если работа есть только для одного? Дайте больше работ и будите больше работников. Заметим что для каких-то целей такая побудка все же годится (напр проснувшиеся могут проверить флажок abort) Когда, я начинал писать двух постов передо мной не было. Когда запостил, каюсь, не посмотрел. Но предложенный вами вариант решение проблемы с numTask - магическое число и это крайне плохое решение. Любой программист с опытом это подтвердит.Однако это не все, вы говорите, что ошибка - пропуск задачи. Рассмотрим систему реального времени (каюсь, моя специлизация, поэтому беру примеры из этой области). Если потребитель зашел в wait позже, чем было выдано очередное задание, то это нештатная ситуация, т.к. при грамотном проектировании у него должен быть запас времени. Если этого запаса не хватило, это значит, что кто-то или что-то отжимает у него процессорные мощности. И если мы сейчас принудим его уйти на обработку мы рискуем сорвать временную диаграмму всей программы. В этом случае единственно верное решение - пропустить побудку и дать этому кому-то завершить свои дела. Такая ситуация и ее решение противоречит с вашим посылом. Вообщем, я мог бы продолжить разговор о том, что вы еще не учли, но он мне не интересен. А читающим он будет бесполезен: все кто сейчас прочитал - те уже сами все выводы сделали, а уши тех, кто будут читать этот тред, что мозг откажиться переваривать много букв. P.S. Ваши комплексы продолжают быть забавными. Старайтесь в том же духе. Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 25, 2012, 10:18 Вместо побудки свободных потоков у вас опять таки идёт побудка какого то "определённого" количества. Читаем первоисточникЦитировать For example, let's suppose that we have three tasks that should be performed whenever the user presses a key. Как мы видим, речь идет о строго определенном, конкретном числе задач (3). Это нормальный, корректный подход к multithreaded, Мы не можем и не должны рассчитывать на то что какие-то нитки нас ждут, но мы железно гарантируем что все 3 будут (так или иначе) выполнены.Управляющий будит рабочих только после полной их отработки? Не врубаетесь в суть. Корректно "после того как все предыдущие задачи завершены". Это совсем не значит что нитка сделавшая задачу "отработала" и уже ждет на wait. Я умышленно выделил это место в ф-цию CreateTask которая может быть получена через copy/paste из исходного примера, но все-таки одну строчку нужно подправить.Теперь такой момент. Автор может публиковать свое решение в том виде в котором считает нужным. Напр я считаю необходимым выделить HandleTask и CreateTask чтобы четко показать структуру алгоритма. Если Вас это не устраивает - это Ваши проблемы, но настойчивые требования все разжевать, положить в рот и помочь проглотить здесь неуместны. Ладно, другой, более веселый разговор (из-за которого собственно я и вернулся в тему) Но предложенный вами вариант решение проблемы с numTask - магическое число и это крайне плохое решение. Любой программист с опытом это подтвердит. Зачем же прятаться за некоего "программиста с опытом"? :) Есть производитель(и), есть потребитель(и). Если производитель ничего не произвел - потребителю нечего потреблять. numTask - число произведенных товаров. Пусть магическое если хотите. Но как Вы представляете обойтись без него? Типа "пусть те потребители которые сейчас ничего не потребляют еще чего-то(?) потребят" - чушь собачья :)Далее Вы рассказываете о Вашей задаче в которой пропуск исходных данных допустим, и даже необходим. Это ассоциируются с теорией Эйнштейна, искривлением пр-ва и времени. А для нормального программиста утерянные данные - это просто баг за который можно получить и который надо исправлять. Поэтому если Вы хотели поговорить о чем-то особенном, изысканном, извращенном - место этому в отдельной теме. А главное: если Вы хотите чего-то доказать - так ДЕЛАЙТЕ это. Предъявите Ваше решение, кратко поясните чем оно лучше другого (напр моего). И все всем станет ясно автоматычно. А так чем больше Вы стараетесь уверить окружающих в собственной крутизне - тем меньше верится. Так что же все-таки мешает нашему танцору (кроме воды)? :) Название: Re: Использование QWaitCondition Отправлено: Dancing_on_water от Декабрь 26, 2012, 09:36 Цитировать А главное: если Вы хотите чего-то доказать Изыди бес, нечистый своими помыслами! Покинь тело человека! До коли память короткая, то я тебе говорил, что здесь не ярмарка тщеславия. И я здесь появился не для того, чтобы что-то доказывать и красоваться. Также, если память коротка, обсуждение началось с выписанной мной из доки схемы. Так, если что-то и доказывал, так это ты.Я же со своей стороны и по мере сил пытаюсь вразумить и направить тебя. Показать, что реальные задачи шире, и что твой подход только запутывают людей. Показать, что мастерство программиста заключается в умении там где надо решить задачу в общем виде, а там где надо применить частное решение. Если продолжаешь упрямиться. То мой тебе совет: почитай по методы синхронизации про примитивы, про то как устроены потоки. Придумайте или найди в opensource себе задачу. Этот тред и твой пост - это все от недостатка опыта решения реальных, а не школьных задач. Название: Re: Использование QWaitCondition Отправлено: Igors от Декабрь 26, 2012, 12:23 Изыди бес, Типичный пост написанный в порыве горячности и неумения контролировать себя. Ничего, в следующий раз перед тем как бросаться словами подумаете что могут попросить за них ответить :)Название: Re: Использование QWaitCondition Отправлено: Kosmonit от Июль 16, 2013, 10:59 Парни подмогните разобраться, начинаю разбираться с многопоточным программирование, это для меня в новинку.
Читаю уже 4й день Ваш пост и не могу воткнуть что и как, где пробои, в чем ошибки примеров, как баран на новые ворота. Набросал код своего Producer и Consumer. Посмотрите есть ли ошибки или все правильно я понял и сделал свой пример. Global var: Код: const int dataSize = 200; CProducer: Код: void run() CConsumer: Код: void run() main: Код: CConsumer consumer1(1); Под конец кода у меня такой вопрос? Нельзя ли заменять цикл: while (listTask.size() == 0) на if(listTask.size() == 0) и while (listTask.size() == bufSize) на if (listTask.size() == bufSize) и в чем разница. Название: Re: Использование QWaitCondition Отправлено: Old от Июль 16, 2013, 11:12 ...или все правильно я понял... Все правильно вы поняли. Под конец кода у меня такой вопрос? Чем мешает цикл? :)Нельзя ли заменять цикл: while (listTask.size() == 0) на if(listTask.size() == 0) и while (listTask.size() == bufSize) на if (listTask.size() == bufSize) и в чем разница. Смотрите, мы добавили одну задачу в очередь и будим все нити. Просыпается первая простаивающая и забирает это задание из очереди, просыпается вторая простаивающая, а задачи и нет. Тогда нить начнет выполнять тело цикла, т.е. заснет на wait опять. Название: Re: Использование QWaitCondition Отправлено: Kosmonit от Июль 16, 2013, 11:21 ...или все правильно я понял... Все правильно вы поняли. Под конец кода у меня такой вопрос? Чем мешает цикл? :)Нельзя ли заменять цикл: while (listTask.size() == 0) на if(listTask.size() == 0) и while (listTask.size() == bufSize) на if (listTask.size() == bufSize) и в чем разница. Смотрите, мы добавили одну задачу в очередь и будим все нити. Просыпается первая простаивающая и забирает это задание из очереди, просыпается вторая простаивающая, а задачи и нет. Тогда нить начнет выполнять тело цикла, т.е. заснет на wait опять. 2. Т.е. while все таки нужен? 3. wakeAll - все потоки одновременно будятся? И выходит кто первый взял задачу тот и король, а все остальные в цикл опять попадают, потому что нет задач? Правильно? Название: Re: Использование QWaitCondition Отправлено: Old от Июль 16, 2013, 11:28 1. Ага, ок Да.2. Т.е. while все таки нужен? 3. wakeAll - все потоки одновременно будятся? И выходит кто первый взял задачу тот и король, а все остальные в цикл опять попадают, потому что нет задач? Правильно? Название: Re: Использование QWaitCondition Отправлено: Igors от Июль 16, 2013, 12:09 wakeAll - все потоки одновременно будятся? И выходит кто первый взял задачу тот и король, а все остальные в цикл опять попадают, потому что нет задач? Правильно? Нет, будятся только те что ждут на WaitCondition, для других wake не имеет эффекта. Поэтому и нужен while. Поскольку Вы создаете 1 задачу, то аккуратнее wakeOne. Название: Re: Использование QWaitCondition Отправлено: Kosmonit от Июль 16, 2013, 12:42 Ок, спасибо, буду разбираться, если что отпишусь не судите строго.
Название: Re: Использование QWaitCondition Отправлено: Kosmonit от Июль 16, 2013, 13:01 Нет, будятся только те что ждут на WaitCondition, для других wake не имеет эффекта. Поэтому и нужен while. Еще разок можно прокомментировать этот момент?Т.е. если поток прерван в другом месте, то WaitCodition его не разбудит это понятно. А вот с while? Не могу воткнуть почему if нельзя сделать? Наверно if можно воткнуть если один поток генерит задачи, а другой обрабатывает а если несколько, то нельзя? Воткните стрелочки где код остановлен в мой код для пояснинения, никак не могу уловить сути. Название: Re: Использование QWaitCondition Отправлено: Igors от Июль 16, 2013, 14:29 Т.е. если поток прерван в другом месте, то WaitCodition его не разбудит это понятно. Прерван (вытеснен) или нет - неважно, если он не успел войти в ожидание то эффект поюудки нулевойА вот с while? Не могу воткнуть почему if нельзя сделать? Наверно if можно воткнуть если один поток генерит задачи, а другой обрабатывает а если несколько, то нельзя? Ну вот допустимВоткните стрелочки где код остановлен в мой код для пояснинения, никак не могу уловить сути. Код Да, ушли на wait, да, проснулись по wake. Но ведь нет никаких гарантий что когда проснулись - в буфере есть место. Напр другой проснулся раньше и успел это место заполнить. Можно опять проверить if'ом но while лучше Edit: смысл в том что wait освобождает мутекс до тех пор пока управление не вернется - а значит ситуация выходит из-под контроля Название: Re: Использование QWaitCondition Отправлено: Kosmonit от Июль 16, 2013, 15:45 Т.е. если поток прерван в другом месте, то WaitCodition его не разбудит это понятно. Прерван (вытеснен) или нет - неважно, если он не успел войти в ожидание то эффект поюудки нулевойА вот с while? Не могу воткнуть почему if нельзя сделать? Наверно if можно воткнуть если один поток генерит задачи, а другой обрабатывает а если несколько, то нельзя? Ну вот допустимВоткните стрелочки где код остановлен в мой код для пояснинения, никак не могу уловить сути. Код Да, ушли на wait, да, проснулись по wake. Но ведь нет никаких гарантий что когда проснулись - в буфере есть место. Напр другой проснулся раньше и успел это место заполнить. Можно опять проверить if'ом но while лучше Edit: смысл в том что wait освобождает мутекс до тех пор пока управление не вернется - а значит ситуация выходит из-под контроля Все, спасибо огромное, кажется начинаю втыкать!!! Название: Re: Использование QWaitCondition Отправлено: Old от Июль 16, 2013, 16:08 Нет Да. Потому что это:будятся только те что ждут на WaitCondition и так очевидно. :)А вот с while? Не могу воткнуть почему if нельзя сделать? Наверно if можно воткнуть если один поток генерит задачи, а другой обрабатывает а если несколько, то нельзя? Смотрите, нить уснула на wait, когда ее будит wake, то управление получит она же, т.е. мы возвращаемся в wait.При этом никто не гарантирует, что задания еще есть и их не выбрали более "быстрые" нитки. Значит, нам нужно после wait, еще раз удостовериться, что задания остались и если их нет, то снова заснуть на wait. Вот эта петля и решает эти действия. Название: Re: Использование QWaitCondition Отправлено: Igors от Июль 17, 2013, 09:44 Смотрите, нить уснула на wait, когда ее будит wake, то управление получит она же, Это бесспорно, но вот тут есть одно подозрительное местоКод а др нитка Код А как мы знаем только одна нитка может владет мутексом. В каком же порядке они им овладевают? Или выходит что пробуждение случится только после того как будящий отдаст мутекс? И если будятся несколько, то понятно что порядок произволен, но может ли пробудившийся рассчитывать на то что остальные или еще спят, или уже отстрелялись и опять ждут на мутексе? Название: Re: Использование QWaitCondition Отправлено: Kosmonit от Июль 17, 2013, 10:29 Смотрите, нить уснула на wait, когда ее будит wake, то управление получит она же, Это бесспорно, но вот тут есть одно подозрительное местоКод а др нитка Код А как мы знаем только одна нитка может владет мутексом. В каком же порядке они им овладевают? Или выходит что пробуждение случится только после того как будящий отдаст мутекс? И если будятся несколько, то понятно что порядок произволен, но может ли пробудившийся рассчитывать на то что остальные или еще спят, или уже отстрелялись и опять ждут на мутексе? QWaitCondition::wakeAll()...SetEvent(current->event); - на ней, когда событие взводится. ??? А в чем слабость выше приведенного Вами кода? Название: Re: Использование QWaitCondition Отправлено: Kosmonit от Июль 17, 2013, 10:59 Это бесспорно, но вот тут есть одно подозрительное место Код а др нитка Код А как мы знаем только одна нитка может владет мутексом. В каком же порядке они им овладевают? Или выходит что пробуждение случится только после того как будящий отдаст мутекс? И если будятся несколько, то понятно что порядок произволен, но может ли пробудившийся рассчитывать на то что остальные или еще спят, или уже отстрелялись и опять ждут на мутексе? Не может такого быть!!! Докладываю как я вижу эту ситуацию!!! Вот эта нитка точно владеет мьютексом: Код
а другая нитка завладеет мьютексом, когда первая сделает и освободит мьтекс: Код
потому что вторая его освободила точно: Код
др. нитка: Код
Название: Re: Использование QWaitCondition Отправлено: Igors от Июль 17, 2013, 11:16 Не может такого быть!!! Докладываю как я вижу эту ситуацию!!! Хммм.... а почему "точно"? Напр wait освободит мутекс, потом опять захватит, почему здесь не так? А по-Вашему выходит что побудка как бы откладывается до тех пор пока будящий не осаободит мутекс. В это верится с трудом - он может заняться чем угодно и даже заснуть на др мутексе.Вот эта нитка точно владеет мьютексом: Что-то Old примолк (наверное изучает pthread_cond_signal) :) Название: Re: Использование QWaitCondition Отправлено: Old от Июль 17, 2013, 11:27 Что-то Old примолк (наверное изучает pthread_cond_signal) :) А вы думаете я буду вам все разжевывать?Этот вопрос отличная тема для самостоятельного изучения, вот разберитесь и доложите нам "как там что". Кстати, на форуме это уже обсуждали и ответ есть в теме, в которой вы принимали бурное участие, только как всегда ничего из нее не вынесли. Название: Re: Использование QWaitCondition Отправлено: Bepec от Июль 17, 2013, 11:46 Некрофилы отакэ... Вроде бы забыли тему, ан нет, опять воду в ступе толкут :/
Название: Re: Использование QWaitCondition Отправлено: Igors от Июль 17, 2013, 12:44 А вы думаете я буду вам все разжевывать? "Разбирайся сам" - ответ на абсолютно любой вопрос. А значит и ценность такого ответа нулевая. Этот вопрос отличная тема для самостоятельного изучения, вот разберитесь и доложите нам "как там что". Кстати, на форуме это уже обсуждали и ответ есть в теме, в которой вы принимали бурное участие, только как всегда ничего из нее не вынесли. И почему Вы думаете что тот ответ верный? Он по существу повторяет последний пост Kosmonit, и, на мой взгляд, расходится со здравым смыслом. Да, и нехорошо пытаться задеть собеседника только потому что ответ Вам неизвестен :) Название: Re: Использование QWaitCondition Отправлено: Old от Июль 17, 2013, 12:51 "Разбирайся сам" - ответ на абсолютно любой вопрос. А значит и ценность такого ответа нулевая. Ответ на вопрос ничего не дает, знания даются при самостоятельном изучении предмета. Поэтому, вы никогда не узнаете ответ на этот вопрос.расходится со здравым смыслом. "Ваш здравый смысл" часто расходиться со здравым смыслом. Форум уже не обращает на это внимание. :)Да, и нехорошо пытаться задеть собеседника только потому что ответ Вам неизвестен :) Вот именно. Поэтому, перечитайте свой пост, на который я отвечал и скажите это себе. :)Название: Re: Использование QWaitCondition Отправлено: Kosmonit от Июль 17, 2013, 13:02 А по-Вашему выходит что побудка как бы откладывается до тех пор пока будящий не осаободит мутекс. Я таки думаю что так, хренушки он опять захватит, пока мьютекс занят, а как освободит так и пробудится....Название: Re: Использование QWaitCondition Отправлено: Kosmonit от Июль 17, 2013, 13:04 Надо будет попробовать смоделировать эту ситуевину!
Название: Re: Использование QWaitCondition Отправлено: Old от Июль 17, 2013, 13:27 Надо будет попробовать смоделировать эту ситуевину! Отладочный вывод после каждой нужной строки и посмотреть на результат. ;)Название: Re: Использование QWaitCondition Отправлено: Igors от Июль 17, 2013, 13:40 Ответ на вопрос ничего не дает, Мне остается только игнорировать такой малосодержательный флуд ...По существу - да, wake не имеет эффекта пока мутекс не освобожден - никто не проснется. Первый пробудившийся захватывает мутекс, остальные еще сидят в wait. Когда этот первый освободит мутекс - следующий выйдет из wait и.т.д Название: Re: Использование QWaitCondition Отправлено: Old от Июль 17, 2013, 13:58 По существу wake это взвод флажочка. Ну это если совсем по существу. :)
Название: Re: Использование QWaitCondition Отправлено: Igors от Июль 17, 2013, 14:14 Хорошо, а вот такой квешн: все рекомендуют использовать wake при захваченном мутексе. Мотивировка типа: без захвата не запрещено, но смысла не имеет. Почему не имеет? Не понимаю куда смысл пропал? :)
Название: Re: Использование QWaitCondition Отправлено: Old от Июль 17, 2013, 14:16 Хорошо, а вот такой квешн: все рекомендуют использовать wake при захваченном мутексе. Мотивировка типа: без захвата не запрещено, но смысла не имеет. Почему не имеет? Не понимаю куда смысл пропал? :) Все это кто?Название: Re: Использование QWaitCondition Отправлено: Kosmonit от Июль 18, 2013, 08:26 Хорошо, а вот такой квешн: все рекомендуют использовать wake при захваченном мутексе. Мотивировка типа: без захвата не запрещено, но смысла не имеет. Почему не имеет? Не понимаю куда смысл пропал? :) Я таки думаю что бы не было такой ситуации, которую Вы описали: Код: bufNotEmpty.wakeAll(); др. нитка: Код: bufNotEmpty.waitl(&mutex); Название: Re: Использование QWaitCondition Отправлено: Old от Июль 18, 2013, 08:52 Я таки думаю что бы не было такой ситуации, которую Вы описали: Такой ситуации не может быть в принципе.wake просто устанавливает флажок, планировщик разбудит ждущую нитку, когда до нее дойдет очередь. Нитка проснется в wait, который попытается сделать мьютексу lock, а если этот мьютекс будет занят кем-то другим, то нитка опять уснет, только на этом мьютексе и проснется, когда он освободится. Название: Re: Использование QWaitCondition Отправлено: Old от Июль 18, 2013, 08:53 Мотивировка типа: без захвата не запрещено, но смысла не имеет. Почему не имеет? Не понимаю куда смысл пропал? :) Понимаю, что "всех" вы сразу вспомнить не смогли. :)Не слушайте "всех", читайте документацию. Там все четко написано, как нужно. Название: Re: Использование QWaitCondition Отправлено: Igors от Июль 18, 2013, 11:17 Ну вот я просто переставил 2 строчки
Код Не вижу чем мне это грозит. Каким образом заклинит? Название: Re: Использование QWaitCondition Отправлено: Kosmonit от Июль 19, 2013, 12:40 Ну вот я просто переставил 2 строчки Я думаю, что ничего не будет, но для перестраховки, я бы поместил разблокировку мьютекса после побудки...Код Не вижу чем мне это грозит. Каким образом заклинит? Название: Re: Использование QWaitCondition Отправлено: Igors от Июль 19, 2013, 12:51 Я думаю, что ничего не будет, но для перестраховки, я бы поместил разблокировку мьютекса после побудки... Я тоже, в конце концов когда-то надо "просто запомнить". Но привести пример когда рухнет если wait не под мутексом - я не могу. Примерчик сделал - работает, но это ничего не доказываетНазвание: Re: Использование QWaitCondition Отправлено: Old от Июль 19, 2013, 12:55 Я думаю, что ничего не будет, но для перестраховки, я бы поместил разблокировку мьютекса после побудки... Зависит от реализации.Вот для pthread четко прописано, будить при захваченом мьютексе. Возможно, где то будет подругому, хотя я сильно сомневаюсь. Сейчас мы по сути пытаемся использовать разделяемый ресурс (условную переменную) без защиты мьютексом. Что может произойти, если две нитки полезут в wake, зависит от реализации этого самого wake. Название: Re: Использование QWaitCondition Отправлено: Igors от Июль 19, 2013, 13:06 Вот для pthread четко прописано, будить при захваченом мьютексе. Не вижу этой четкости, напрhttp://stackoverflow.com/questions/4544234/calling-pthread-cond-signal-without-locking-mutex (http://stackoverflow.com/questions/4544234/calling-pthread-cond-signal-without-locking-mutex) Доказательство там очень неубедительное Название: Re: Использование QWaitCondition Отправлено: Old от Июль 19, 2013, 13:13 Аааааа. Вы бы еще ссылку на Хабр выложили. :)
Название: Re: Использование QWaitCondition Отправлено: Igors от Июль 19, 2013, 13:18 Аааааа. Вы бы еще ссылку на Хабр выложили. :) По-моему stackoverflow - очень толковый сайт. Ну и никто не мешает Вам привести действительно авторитетный (по Вашему мнению) первоисточник, а еще лучше - сценарий краша "по ходам". Название: Re: Использование QWaitCondition Отправлено: Old от Июль 19, 2013, 14:46 По-моему stackoverflow - очень толковый сайт. Почему вы тогда не верите написанному там? :)Ну и никто не мешает Вам привести действительно авторитетный (по Вашему мнению) первоисточник. man pthread_cond_signalа еще лучше - сценарий краша "по ходам". А еще лучше! (http://www.prog.org.ru/index.php?topic=23820.msg180658#msg180658)Название: Re: Использование QWaitCondition Отправлено: Igors от Июль 19, 2013, 15:22 Почему вы тогда не верите написанному там? :) Так а что ж там написаноЦитировать Process B (incorrect): То ясно что если я переменную condition меняю не под мутексом - отгребу. Но вот почему pthread_cond_signal должен быть внутри - хзcondition = TRUE; pthread_cond_signal(&cond); А еще лучше! (http://www.prog.org.ru/index.php?topic=23820.msg180658#msg180658) Ну и чего ото делать вид что это якобы очевидно? :) Не надо бояться сказать "не знаю", это часто проще и лучшеНазвание: Re: Использование QWaitCondition Отправлено: Old от Июль 19, 2013, 15:26 Ну и чего ото делать вид что это якобы очевидно? :) Для меня да. Вызов pthread_cond_signal(&cond); это доступ к разделяемому ресурсу без защиты мьютексом. Может быть все что угодно в зависимости от реализации. Не надо бояться сказать "не знаю", это часто проще и лучше Проще учиться думать и разбираться самому, а не спрашивать по форумам.Название: Re: Использование QWaitCondition Отправлено: Igors от Июль 19, 2013, 16:03 Проще учиться думать и разбираться самому, а не спрашивать по форумам. А я и не просил Вас ни о какой помощи :) Просто интересно "почему". Хорошо, вот еще попытка доказательстваЦитировать This is valid: Обратите внимание что вызов pthread_cond_signal не требует защиты (то же и в др источниках). Да, побудка будет упущена, в этом автор прав. Но как мы знаем, само по себе это не криминал. Если до того мы взвели go (под защитой) - то должно работать, задача не пропускаетсяvoid *threadproc(void *data) { printf("Sending go signal\n"); go = 1; pthread_cond_signal(&cond); } However, consider what's happening in main while(!go) { /* Suppose a long delay happens here, during which the signal is sent */ pthread_cond_wait(&cond, &lock); } If the delay described by that comment happens, pthread_cond_wait will be left waiting—possibly forever. This is why you want to signal with the mutex locked Код Или я ошибаюсь? Название: Re: Использование QWaitCondition Отправлено: Old от Июль 19, 2013, 16:13 Или я ошибаюсь? Если несколько ниток будут писать и читать int без защиты мьютексом, будет работать?Вроде будет, а потом... а на другой платформе... а на другой архитектуре... Поэтому, мне совершенно не понятно, что доказывает (или не доказывает) этот пример. Еще раз, я думаю, что разработчики pthread настаивают на вызове signal под защитой мьютекса, потому что в реализации самих функций работы с условной переменной (pthread_cond_xxx) могут быть "тонкие места", а не в пользовательском коде. Название: Re: Использование QWaitCondition Отправлено: Igors от Июль 19, 2013, 16:40 Если несколько ниток будут писать и читать int без защиты мьютексом, будет работать? Как ни странно, в схеме WaitCondition - будет :) За счет второй переменной которая строго под мутексом. Вроде будет, а потом... а на другой платформе... а на другой архитектуре... Да конечно практичнее впихнуть под мутекс чем разбираться - я ж с этим не спорю. Но какой-то Вы совсем не любознательный, хотя еще молодой :) Название: Re: Использование QWaitCondition Отправлено: Old от Июль 19, 2013, 16:46 Но какой-то Вы совсем не любознательный, хотя еще молодой :) А в чем здесь любознательность? Сейчас условные переменные реализовали так, завтра их реализуют по другому, под какой нибудь вендой по третьему? Мне нужно все изучить? Любознательный вы наш? :)хотя еще молодой :) Нуу 40 лет это не возраст для мужчины. ;D |