Интернет магазин китайских планшетных компьютеров |
|
Компьютеры - Проблема ABA - Пример15 июня 2011Оглавление: 1. Проблема ABA 2. Пример 3. Обходные решения Рассмотрим lock-free стек: /* Наивная реализация lock-free стека, страдающая проблемой ABA.*/ class Stack { volatile Obj* top_ptr; // // Снимает верхний элемент и возвращает указатель на него. // Obj* Pop { while { Obj* ret_ptr = top_ptr; if return NULL; Obj* next_ptr = ret_ptr->next; // Если верхний элемент - всё ещё ret, считаем, что никто не менял стек. // // Атомарно заменяем top на next. if ) { return ret_ptr; } // Иначе - стек изменён, пробуем заново. } } // // Добавляет obj_ptr на вершину стека. // void Push { while { Obj* next_ptr = top_ptr; obj_ptr->next = next_ptr; // Если верхний элемент - всё ещё next, считаем, что никто не менял стек. // // Атомарно заменяем top на obj. if ) { return; } // Иначе - стек изменён, пробуем заново. } } }; Этот код обычно может предотвращать проблемы с конкурентным доступом, но страдает проблемой ABA. Рассмотрим следующую последовательность: Изначально стек содержит top → A → B → C Поток 1 начинает выполнять pop: ret = A; next = B; Поток 1 прерывается непосредственно перед CompareAndSwap... { // Поток 2 выполняет pop: ret = A; next = B; CompareAndSwap // Удача, top = B return A; } // Теперь на стеке top → B → C { // Поток 2 выполняет pop ещё раз: ret = B; next = C; CompareAndSwap // Удача, top = C return B; } // Теперь на стеке top → C delete B; { // Поток 2 добавляет A обратно на стек: A->next = C; CompareAndSwap // Удача, top = A } Теперь стек содержит top → A → C Поток 1 продолжает работу: CompareAndSwap Эта инструкция выполняется успешно, поскольку top == ret, то она присваивает top значение next. Но B было уничтожено! Это приведёт к плохим последствиям... Просмотров: 2640
|