Ответ
CAS (Compare-And-Swap) — это атомарная инструкция, выполняемая на уровне процессора, которая позволяет реализовать безопасные конкурентные изменения данных без использования блокировок (мьютексов).
Как это работает:
Операция принимает три аргумента:
- Указатель на значение в памяти (
addr
). - Ожидаемое старое значение (
old
). - Новое значение (
new
).
Процессор атомарно (непрерываемо) выполняет следующее:
- Сравнивает текущее значение по адресу
addr
сold
. - Если они равны, то записывает по адресу
addr
значениеnew
и возвращаетtrue
. - Если они не равны (значит, другой поток уже изменил данные), операция ничего не меняет и возвращает
false
.
Пример в Go (пакет sync/atomic
):
import (
"fmt"
"sync/atomic"
)
func main() {
var counter int64 = 0
// Попытка увеличить счетчик с 0 до 1.
// &counter - адрес переменной
// 0 - ожидаемое старое значение
// 1 - новое значение
swapped := atomic.CompareAndSwapInt64(&counter, 0, 1)
fmt.Printf("Операция успешна: %v, новое значение: %dn", swapped, counter)
// Вывод: Операция успешна: true, новое значение: 1
// Повторная попытка с тем же старым значением (0) провалится,
// так как текущее значение уже 1.
swapped = atomic.CompareAndSwapInt64(&counter, 0, 2)
fmt.Printf("Операция успешна: %v, новое значение: %dn", swapped, counter)
// Вывод: Операция успешна: false, новое значение: 1
}
Преимущества и использование:
- Производительность: CAS позволяет создавать "lock-free" алгоритмы, которые могут быть значительно быстрее мьютексов в условиях высокой конкуренции, так как не блокируют потоки.
- Реализация конкурентных структур: На основе CAS строятся многие высокоуровневые примитивы синхронизации и структуры данных, например, lock-free очереди, стеки и даже некоторые части реализации каналов в Go.