TGViewer
Loser story Loser story @reverse13 · 946 subscribers
Post #666 818
Сегодня расскажу что-то полезное.
Это wait-free "алгоритм" для некоторого подобия взаимного исключения и очереди. Звучит конечно круто, но на практике это простейший код, как и почти все действительно полезные wait/lock-free алгоритмы.

Допустим есть некоторая асинхронная операция, с общим состоянием, запрос на ее вызов может возникать в разных тредах.
При этом операцию нельзя исполнять параллельно, она требует взаимного исключения.
Также есть одно важное дополнительное условие, нам неважно сколько раз была вызвана операция, но при этом мы хотим, чтобы наиболее актуальный вызов был совершен, ну и конечно мы не хотим делать бесполезную работу.

Наверно нихуя не понятно, я не умею нормально объяснить, приведу пример.

Допустим у вас есть некоторая тяжёлая операция, например пересчитать какой-то кеш, эта операция выполняется в отдельном потоке, а запрос на нее приходит из вызов в разных тредах, часть зависит от действий юзера, часть по таймауту, етс
Самое банальное решение просто очередь задач под мьютексом.
Понятно, что оно не оптимально именно с точки зрения того, что операция будет вызываться множество раз, даже если это уже не нужно.

Оптимально будет сделать так:

void forceAsyncRequest() {
some_thread.push([this] {
counter_.store(1);
...do it...
// если за это время пришел новый asyncRequest мы перезапустим сами себя в конце
if (counter_.fetch_sub(1) > 1) {
forceAsyncRequest();
}
}
}

void asyncRequest() {
if (counter_.fetch_add(1) == 0) {
forceAsyncRequest();
}
}

Я написал такой код ещё в транзасе, там было обновление кеша прореживания объектов по таймауту, а также некоторым действиям пользователя.
Там также нашлось несколько других мест где этот паттерн был полезен.

И недавно мне понадобился этот "алгоритм" в ArangoDB, решил с вами поделиться)

Кстати в yaclib (star plz https://github.com/YACLib/YACLib) я все планирую написать специальный тип таски на такой паттерн (там ещё в push аллокации не будет), да все руки не доходят (issue есть: https://github.com/YACLib/YACLib/issues/10)
GitHub GitHub - YACLib/YACLib: Yet Another Concurrency Library Yet Another Concurrency Library. Contribute to YACLib/YACLib development by creating an account on GitHub.
More from @reverse13
  1. Jul 29, 2026Вообще мы тут сделали end-to-end search/analytics benchmarks на 1e9 otel logs Планируем ту…
  2. Mar 19, 2026Последние пару месяцев смотрел и правил перф серчевого движка и в общем у нас наконец-то е…
  3. Dec 23, 2025Мы тут написали небольшой пост про свой iobuf который юзаем для реализации postgres проток…
  4. Dec 2, 2025Привет, мы частично заопенсорсили текущий код нашего проекта -- SereneDB. Это оказалось тя…
  5. Sep 28, 2025Вообще вот странная штука, больших проектов на C++, C, Rust которые делают базы данных или…
  6. Aug 30, 2025Решил почитать перед сном коммиты в llvm libc++, а то там llvm 21 вышел, думаю может обнов…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →