Я натолкнулся на очередь без блокировки, которая поддерживает мультипроизводителя и потребителя, операция проталкивания очереди выглядит следующим образом
inline void push(LT* item)
{
LT *old = pushlist.load(std::memory_order_relaxed);
do {
item->next = old;
} while (!pushlist.compare_exchange_weak(old, item,
std::memory_order_release));
}
pushlist
- переменная атомарного указателя иЯ имею в виду сценарий, где два потока находятся в этом коде
Thread1:
- T1 # Загружает указатель (не будет LOCK # ничего)
- T2 # Переходит в цикл и подключает голову (
old
) к новому элементу - T3 # Теперь в cmpxchg (LOCK #);он ожидает, что head (
old
) будет * this--, что верно, поэтому своп будет успешным
Thread2:
- T2 # Загружает указатель (ничего не будет LOCK #)
- T3 # Идет зацикливание и зацепление головы (
old
) в новый элемент - T4 # Теперь cmpxchg будет ожидать голову (
old
) быть * this--, что, я думаю, не потому, что Thread1 уже изменил его, поэтому old
больше не является главой, операция будет неудачной ...... сейчас, не будет лиspin?
Я проверил, отлично работает, но мне не ясно, как это.
auto work = [&p](auto name){
int i{0};
linked_item<int> dummy{};
for(; i < 100 ; ++i){
p.push(&dummy);
}
std::cout<<name<<" finished"<< i << "\n";
};
std::thread t1{work, "t1"}, t2{work, "t2"};
t1.join(); t2.join();