繁体   English   中英

具有单个生产者单个使用者的无锁循环缓冲器

[英]Lockless circular buffer with single producer singular consumer

我有一个使用者线程,它永远不能锁定或分配内存,一个生产者线程可以。 我想实现一个两处循环缓冲区,以便能够从生产者向消费者线程提供数据,并且有一个界限,即每当没有新数据可供使用时,消费者就将重用已经可用的数据。

这是我现在想出的:

bool newDataAvailable = false;
bool bufferEmpty = true;

foo* currentData = new foo();
foo* newData = new foo();

void consumer() {
  while(true) {
    currentData->doSomething();
    if(newDataAvailable) {
      foo* tmp = currentData;

      // Objects are swapped so the old one can be reused without additional allocations
      currentData = newData;
      newData = tmp;
      newDataAvailable = false;
      bufferEmpty = true;
    }
  }
}

void producer() {
  while(true) {
    while(!bufferEmpty) { wait(); }
    newData->init();
    bufferEmpty = false;
    newDataAvailable = true;
  }
}

这个天真的实现可以吗? 我知道对变量的读写可能是非原子的,因此我应该使用原子存储,但这会导致锁定。 这里需要使用原子存储吗? 另外,我想消除生产者中的主动等待,我认为我可以使用std::condition_variable ,但是它们需要使用互斥体,因此我负担不起。

编写不使用互斥量共享变量的多线程代码非常困难。 请参见无锁编程简介 ,无锁缓冲区

如果您绝对必须避免使用互斥锁,那么我强烈建议您使用预制的无锁队列,例如Boost.lockfreeMPMCQueue作为轻量的非增强型替代方法。

我知道对变量的读写可能是非原子的,因此我应该使用原子存储,但这会导致锁定。

std::atomic通常对所有原始类型(不超过您的CPU的本机大小)都是无锁的(不使用互斥锁)。 您可以通过调用std::atomic<T>::is_lock_free来检查std::atomic是否将互斥体用于给定类型

这里需要使用原子存储吗?

是的,一点没错。 您需要使用互斥或​​原子。

另外,我想消除生产者中的活动等待,我认为我可以使用std :: condition_variable

当您不能使用互斥锁时,唯一的选择是使用自旋锁。 如果在您的上下文中允许,则可以在自旋锁中使用std::this_thread::yield()来减少CPU负载。 (但是互斥锁可能会更快)

编辑:仅2个原子的潜在解决方案是:

std::atomic<foo*> currentData = new foo();
std::atomic<foo*> newData = new foo();

void consumer() {
    foo* activeData = currentData;
    while (true) {
        activeData->doSomething();
        foo* newItem = currentData;
        if (newItem != activeData) {
            newData = activeData;
            activeData = newItem;
        }
    }
}

void producer() {
    while (true) {
        foo* reusedData = newData;
        if (!reusedData)
            continue;
        newData = nullptr;
        reusedData->init();
        currentData = reusedData;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM