Интернет магазин китайских планшетных компьютеров |
|
Компьютеры - Проблема 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 было уничтожено! Это приведёт к плохим последствиям... Просмотров: 3035
|