|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
||||||
Условные переменные и ложные пробуждения30.01.2018, 22:27. Показов 5000. Ответов 24
Метки нет (Все метки)
Есть код
когда dataProvider вызовет notify_one, то функция потока dataCheker проснется и проверит условие. Если условие ложно - поток пойдет спать дальше и так до тех пор пока коллбек не вернет true. Но тут насколько я понимаю есть следующая проблема: За несколько микросекунд до того как будут готовы данные, может случиться ложное пробуждение, и таким образом поток как я понимаю "проскочит" т.к данные будут готовы только через несколько микросекунд и т.к колбек вернет false, поток уснет и пойдет новый отсчет таймаута равный одной минуте. В итоге программа будет ждать еще одну лишнюю минуту... Если такая проблема есть, то можно ли как нибудь избавиться от нее не отказываясь от использования условных переменных?
0
|
||||||
| 30.01.2018, 22:27 | |
|
Ответы с готовыми решениями:
24
QWaitCondition и ложные пробуждения Условные переменные Повторяю за Пузаном. Условные переменные (COND) |
|
184 / 192 / 48
Регистрация: 25.08.2011
Сообщений: 792
|
|
| 30.01.2018, 22:43 | |
|
а зачем атомик переменную еще и кондишенал защищать?
0
|
|
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|
| 30.01.2018, 23:05 [ТС] | |
|
1Вирт1,
Атомик поставил чтоб барьер памяти был (хотя наверное уместнее было бы использовать atomic_thread_fence) Иначе компилятор насколько я знаю мог бы переупорядочить код так, что бы сначала вызвался notify_one, а потом данные были бы сохранены в не атомик переменную. До сохранения второй поток пробудился бы и в результате того что код был переупорядочен (возможно), данные были бы ещё не готовы.
0
|
|
|
192 / 128 / 52
Регистрация: 19.01.2010
Сообщений: 518
|
||
| 30.01.2018, 23:24 | ||
|
0
|
||
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|
| 30.01.2018, 23:48 [ТС] | |
|
Selot,
Так у атомика вторым параметром и есть мемори ордер Установлено значение по умолчанию поэтому явно передавать не стал Добавлено через 1 минуту Selot, У интела х86 вроде как не переставляет код Тоже такое слышал Добавлено через 16 минут Selot, Кстати вы вроде сейчас говорите про барьеры компилятора Реордеринг вроде как двухуровневый 1. На уровне компилятора 2. На уровне процессора Если компилятор не увидит барьер памяти То по идее независимо от типа процессора может переставить две строки местами Потому что с его точки зрения логика не нарушится Компилятор по идее рассматривает код как однопоточный А вот процессор уже реордерить тот код (с переставленными строками) который ему дали не будет (если конечно же проц не выполняет реордеринг, как х86, если мы оба не ошибаемся) Добавлено через 54 секунды И получится в итоге не работающая программа
0
|
|
|
What a waste!
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
|
|
| 31.01.2018, 06:48 | |
|
Undisputed, надо вызывать notify в крит. секции, иначе запись во флаг + notify в продюсере могут "вклиниться" между проверкой флага в предикате и слипом в консьюмере.
0
|
|
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|
| 31.01.2018, 09:01 [ТС] | |
|
gray_fox,
Не очень понял что здесь не так Там же только один поток который может вызвать нотифай. Было бы их больше, тогда наверное крит. секция понадобилась Консьюмер спит до тех пор пока мы не вызовем нотифай, поэтом туда ничего вклиниваться не должно т.к это на момент записи вообще не рабочий кусок кода. Он проснётся когда мы запишем данные и вызовем нотифай (ну или в случае ложного пробуждения) Добавлено через 37 минут gray_fox, Вот тут есть пример для wait_for с колбеком, там так же у продюсера нет мьютекса http://ru.cppreference.com/w/c... e/wait_for А в версии wait_for без колбека мьютекс есть http://ru.cppreference.com/w/c... n_variable Во втором варианте с большой вероятностью мьютекс был использован только потому что бы сохранить порядок выполнения операций записи (наличие мьютекса неявно приводит к установки барьеров запрещающих реордеринг) Иначе могло бы получиться так, что notified был бы равен true раньше чем данные попали бы в очередь ...
0
|
|
|
71 / 59 / 14
Регистрация: 20.12.2013
Сообщений: 720
|
||
| 31.01.2018, 09:01 | ||
|
p.s. и ложное пробуждение ведь тоже только для "plain wait(lck)"
0
|
||
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
||
| 31.01.2018, 10:20 [ТС] | ||
|
AndrSlav,
Нет, для wait_for так же есть вероятность ложного пробуждения Посмотрите тут описание http://ru.cppreference.com/w/c... e/wait_for Дело в том что может случиться ложное пробуждение прямо перед тем как наступит таймаут, пока будет тратиться время на ложное пробуждение, часики нас ждать не будут, соответственно время отведённое на таймаут мы проскочим и поток уснёт снова, а следующее пробуждение уже будет по новому таймауту т.к прежний мы уже проскочили, и так может повторяться сколько угодно раз Добавлено через 47 минут AndrSlav, Небольшое уточнение: каждое "просыпание", независимо от того было ли оно ложным, приводит к повторному сну потока с новым таймаутом. wait_for вернёт управление лишь тогда, когда предикат вернёт true.
Нужно юзать wait_until, там подобных проблем не возникает. Правда может быть небольшая задержка ввиду тех же ложных пробуждений, но циклически это происходить не будет. При желании можно организовать повторные вызовы wait_until, вызовы делать в цикле, но уже с изменённым сроком который можно вычислять после каждого пробуждения...
1
|
||
|
71 / 59 / 14
Регистрация: 20.12.2013
Сообщений: 720
|
||||||||||
| 31.01.2018, 10:27 | ||||||||||
Добавлено через 5 минут
1
|
||||||||||
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|||
| 31.01.2018, 10:44 [ТС] | |||
![]() обратите внимание в вашем примере использовано wait_until, а у меня wait_for по тому принципу который я описал в сообщении выше (в добавлении) It may also be unblocked spuriously. When unblocked, regardless of the reason, lock is reacquired and wait_for() exits. If this function exits via exception, lock is also reacquired. (until C++14) 2) Equivalent to return wait_until(lock, std::chrono::steady_clock::now() + rel_time, std::move(pred));. This overload may be used to ignore spurious awakenings.
0
|
|||
|
71 / 59 / 14
Регистрация: 20.12.2013
Сообщений: 720
|
||
| 31.01.2018, 10:47 | ||
|
упс, не прав - пойду читать еще: вывелось 3 раза wait.
Добавлено через 1 минуту хотя... или просто проверка несколько раз может пройти, но через 10 сек по любому будет выход - сейчас пока такую мысль думаю. Добавлено через 1 минуту
0
|
||
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
||
| 31.01.2018, 10:50 [ТС] | ||
|
обратите внимание в вашем примере использовано wait_until по тому принципу который я описал в сообщении выше (в добавлении), а у меня wait_for извиняюсь за кривость сообщений пишу торопясь
0
|
||
|
71 / 59 / 14
Регистрация: 20.12.2013
Сообщений: 720
|
||
| 31.01.2018, 10:51 | ||
|
0
|
||
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
||
| 31.01.2018, 10:57 [ТС] | ||
|
но если вы хотите избавиться от ложных просыпаний можете использовать wait_until переназначая время ожидания я сейчас должен покинуть форум, если найдете доп. инфу буду благодарен если поделитесь пока думаю так: если уж использовать wait_for, то только в цикле в предикате нужно возвращать true что бы понять были ли подготовлены данные которые мы ждем далее если result будет false, значит данных нет и пробуждение ложное и следующая итерация в цикле снова залочит wait_for на указанный таймаут и так по кругу
0
|
||
|
71 / 59 / 14
Регистрация: 20.12.2013
Сообщений: 720
|
|||||||||||
| 31.01.2018, 11:23 | |||||||||||
|
Может так?
ps ну и обязательно
0
|
|||||||||||
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|
| 31.01.2018, 12:04 [ТС] | |
|
AndrSlav,
Да именно так же думаю и я Постараюсь вечером более подробно все расписать, все выводы которые у меня появились в этой теме Ща с телефона не удобно писать много текста Только не понял зачем вы поставили лок перед notify Можете пошагово описать ситуацию при которой отсутствие лока перед нотифай может навредить?
0
|
|
|
71 / 59 / 14
Регистрация: 20.12.2013
Сообщений: 720
|
|
| 31.01.2018, 13:01 | |
|
0
|
|
|
What a waste!
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
|
||
| 31.01.2018, 18:38 | ||
|
1) dataChecker засыпает в wait_for, просыпается (ложное пробуждение) и захватывает мютекс m, проверяет условие flag > 0. 2) dataProvider сохраняет значение во flag и вызывает notify. dataChecker этот сигнал не получит, ведь он ещё не спит. 3) dataChecker освобождает мютекс и засыпает на оставшееся по таймеру время.
2
|
||
|
71 / 59 / 14
Регистрация: 20.12.2013
Сообщений: 720
|
|||||||
| 31.01.2018, 19:17 | |||||||
|
Да, все же нужен лок)
В дополнение к gray_fox http://en.cppreference.com/w/c... notify_one
https://msdn.microsoft.com/ru-... 74724.aspx
0
|
|||||||
| 31.01.2018, 19:17 | |
|
Помогаю со студенческими работами здесь
20
Сменить кнопку пробуждения Синий экран после пробуждения Ноутбук зависает после пробуждения
Ложные пользователи форума Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
||||
|
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта
Симптом:
После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
|
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
|
Новый ноутбук
volvo 07.12.2025
Всем привет.
По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне:
Ryzen 5 7533HS
64 Gb DDR5
1Tb NVMe
16" Full HD Display
Win11 Pro
|
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
|
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
|
|
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов
На странице:
https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/
нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
|
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов.
. . .
|
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
|
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
|
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут.
В век Веб все очень привыкли к дизайну Single-Page-Application .
Быстренько разберем подход "на фреймах".
Мы делаем одну. . .
|