我已经实现了Michael和Scott Queue(并发无锁队列),并且出队操作代码重复存在问题。通常,这个问题不是关于队列算法本身的,而是关于如何干净地实现函数的几种变体的大多数具有相同的结构。我说的例子:
bool dequeue() {
while(true) {
// [atomically load head, tail and head->next]
auto head = m_head.load(std::memory_order_acquire);
auto head_ptr = head.get();
auto tail = m_tail.load(std::memory_order_acquire);
auto next = head_ptr->next.load(std::memory_order_acquire);
auto next_ptr = next.get();
// Are head, tail, and next consistent?
if(head == m_head.load(std::memory_order_acquire)) {
// Is queue empty or tail falling behind?
if(head_ptr == tail.get()) {
// Is queue empty?
if(!next_ptr) {
return false;
}
// tail is falling behind. Try to advance it
m_tail.compare_exchange_strong(tail, tail(next_ptr));
} else if(next_ptr){
// [ above check is result free list interaction, not part of orginal algo ]
// [Read value from next_ptr->data]
// <<<variant of operation here>>>>
}
}
}
}
我已经计划实施各种操作来代替<<<variant of operation here>>>>
包括逻辑,if-else代码退出循环等,我想避免重复主代码函数的主体。我应该如何进行?我至少使用C ++ 14标准。背景故事是boost :: lockfree :: queue <>太受限制,我想实现诸如pop_if()
,compare_front()
,begin()
之类的所有操作[<<<variant operation here>>>
部分除外,共享相同的基本出队操作代码逻辑。
如果我理解正确,则可以创建带有参数的泛型方法-仿函数
template <class Func>
bool dequeue_generic(Func func) {
....
func(next_ptr->data)
}
然后使用不同函子的实现方法来处理数据。