我已经实现了Michael和Scott队列(一个并发的无锁队列(,并且我遇到了出列操作代码重复的问题。这个问题通常不是关于队列算法本身,而是如何干净地实现几种函数变体它们大多具有相同的结构。我说的例子是:
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>>>>
包括逻辑,如果其他代码退出循环等等,我希望避免复制主函数的主体。我应该如何继续?我至少使用C++14标准。背景故事是boost::lockfree::queue<>受到太多限制我想实现pop_if()
、compare_front()
、begin()
这样的操作除了CCD_ 5部分之外,共享相同的基本出列操作代码逻辑。
如果我理解正确,你可以创建一个带参数的泛型方法——一个函子
template <class Func>
bool dequeue_generic(Func func) {
....
func(next_ptr->data)
}
然后implement方法使用不同的函子来处理数据。