Если атомарные операции lock_free
, они, вероятно, реализованы так же, как реализованы компоненты мьютекса. В конце концов, чтобы заблокировать мьютекс, вам действительно нужна какая-то атомарная операция, гарантирующая, что один и только один поток заблокирует мьютекс.
Разница в том, что атомарные операции, которые не блокируются, не имеют «заблокированного» состояния. Давайте сравним два возможных способа атомарного приращения переменной:
Во-первых, мьютексный способ. Мы блокируем мьютекс, читаем-увеличиваем-записываем переменную, затем разблокируем мьютекс. Если поток будет прерван во время чтения-инкремента-записи, другие потоки, пытающиеся выполнить ту же операцию, будут заблокированы, пытаясь заблокировать мьютекс. (См. Где находится блокировка для std::atomic? для как это работает в некоторых реальных реализациях, для объектов слишком больших, чтобы быть lock_free.)
Во-вторых, атомный способ. ЦП «блокирует» только строку кэша, содержащую переменную, которую мы хотим изменить, на время выполнения одной инструкции чтения-увеличения-записи. (Это означает, что ЦП задерживает ответ на запросы MESI о признании недействительной или совместном использовании строки кэша, сохраняя эксклюзивный доступ, чтобы ни один другой ЦП не мог просмотреть ее. Когерентность кэша MESI всегда требует исключительного владения строкой кэша, прежде чем ядро сможет изменить ее, поэтому это дешево, если мы уже владели линией). Мы не можем быть прерваны во время инструкции. Другой поток, пытающийся получить доступ к этой переменной, в худшем случае должен ждать, пока аппаратное обеспечение когерентности кеша определит, кто может изменять расположение памяти.
Так как же нам заблокировать мьютекс? Вероятно, мы выполняем атомарное сравнение и обмен. Таким образом, легкие атомарные операции — это примитивы, из которых собираются тяжелые операции мьютексов.
Конечно, это все зависит от платформы. Но это то, что делают типичные современные платформы, которые вы, вероятно, будете использовать.
person
David Schwartz
schedule
05.12.2019
std::atomic
реализовано по разному на разных архитектурах, то думаю мне достаточно одного примера на какой-то конкретной архитектуре, например X86. - person Yves   schedule 05.12.2019