Информация об изменениях

Сообщение Re: C++11: Синхронизация - Условные переменные и ложные проб от 13.03.2019 8:42

Изменено 13.03.2019 9:34 kotalex

Re: C++11: Синхронизация - Условные переменные и ложные пробужде
Здравствуйте, rsdn_179b, Вы писали:

_>Здравствуйте гуру, знатоки и просто ценители C++ !


_>Интересует собственно сабж — откуда берутся эти самые "ложные пробуждения" ?


_>Поиск по форуму к сожалению не дал ответа на этот вопрос.


_>Например гражданин Кодт в одном из постов
Автор: Кодт
Дата: 08.04.13
пишет следующее:


_>

... Правильный взгляд даёт понимание таких вещей, и как ложные пробуждения ...


_>Но к сожалению не объясняет самой сути этого явления.


_>Зачем крутиться в цикле и проверять какие-то условия



_>Пример кода взят с "CodeProject":


_>
_>#include <thread>
_>#include <mutex>
_>#include <condition_variable>
_>#include <iostream>
_>#include <queue>
_>#include <random>

_>...
_>std::mutex              g_lockqueue;
_>std::condition_variable g_queuecheck;
_>...
_>bool                    g_notified;



_>void workerfunc(int id, std::mt19937& generator)
_>{
_>    ...
_>    g_notified = true;
_>    g_queuecheck.notify_one();
_>    ...
_>}

_>void loggerfunc()
_>{
_>    ...
_>    std::unique_lock<std::mutex> locker(g_lockqueue);

_>    while(!g_notified) // used to avoid spurious wakeups 
_>    {
_>        g_queuecheck.wait(locker);
_>    }
_>    ...
_>}
_>





_>Надеюсь на содержательные ответы. Всем ответившим заранее спасибо.



_>П.С.: Ссылки на соответствующие учёные книги приветствуются


_>Интересует собственно сабж — откуда берутся эти самые "ложные пробуждения" ?

Для POSIX: дело в устройстве самого механизма. Pthread основан на futex. В основе futex идёт (первым аргументом) адрес некоторой переменной (назовём её 'A'). Далее внутри реализации происходит преобразование адреса переменной из "пользовательского пространства" в физический адресс (это нужно для shared операций между процессами). Далее от полученного адреса вычисляется 32 битный хэш (так называемый jhash2). Затем вычисляется индекс: от полученного значения берётся маска, что-то типа ( hash & ((1<<20) — 1 ) ). Значение этой маски сильно зависит от системы (настроек, количества процессоров), но обычно она не превышает 1 МБ. Полученный индекс используется для индексации в глобальной таблице, описывающей все futex-объекты. В итоге, если есть в системе какой-либо другой процесс у которого есть своя переменная 'B' и индекс, подсчитанный от этой переменной совпадёт с индексом переменной 'A' и "выставится событие" по переменой 'B' — то выставится это-же событие и для переменной 'A', т.е. для неё произойдёт "ложное пробуждение". Вероятность данного явления небольшая, но всё-же есть.
Re: C++11: Синхронизация - Условные переменные и ложные проб
Здравствуйте, rsdn_179b, Вы писали:

_>Интересует собственно сабж — откуда берутся эти самые "ложные пробуждения" ?

Для POSIX: дело в устройстве самого механизма. Pthread основан на futex. В основе futex идёт (первым аргументом) адрес некоторой переменной (назовём её 'A'). Далее внутри реализации происходит преобразование адреса переменной из "пользовательского пространства" в физический адресс (это нужно для shared операций между процессами). Далее от полученного адреса вычисляется 32 битный хэш (так называемый jhash2). Затем вычисляется индекс: от полученного значения берётся маска, что-то типа ( hash & ((1<<20) — 1 ) ). Значение этой маски сильно зависит от системы (настроек, количества процессоров), но обычно она не превышает 1 МБ. Полученный индекс используется для индексации в глобальной таблице, описывающей все futex-объекты. В итоге, если есть в системе какой-либо другой процесс у которого есть своя переменная 'B' и индекс, подсчитанный от этой переменной совпадёт с индексом переменной 'A' и "выставится событие" по переменой 'B' — то выставится это-же событие и для переменной 'A', т.е. для неё произойдёт "ложное пробуждение". Вероятность данного явления небольшая, но всё-же есть.