Push-операция без блокировки очереди с использованием compare_exchange_weak - PullRequest
1 голос
/ 16 октября 2019

Я натолкнулся на очередь без блокировки, которая поддерживает мультипроизводителя и потребителя, операция проталкивания очереди выглядит следующим образом

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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...