标签: circular-buffer

在磁盘上实现固定大小的日志文件或循环缓冲区

我查了这个问题,但这不是我想要的.

我正在试图找出如何限制日志文件的大小(比方说,10MB),并且一旦它被击中,就会:

  • 开始写作开头,而不是追加,或
  • 继续追加,但在我这样做时从头开始删除内容

不要真的关心语言 - 只要有可能:)


注意:我知道滚动日志文件方法(达到目标大小,重命名并继续记录).我希望避免这样的滚动.

file-io logging buffer circular-buffer

9
推荐指数
1
解决办法
1万
查看次数

了解Linux内核循环缓冲区

有一篇文章在http://lwn.net/Articles/378262/上描述了Linux内核的循环缓冲区实现.我有一些问题:

这是"生产者":

spin_lock(&producer_lock);

unsigned long head = buffer->head;
unsigned long tail = ACCESS_ONCE(buffer->tail);

if (CIRC_SPACE(head, tail, buffer->size) >= 1) {
    /* insert one item into the buffer */
    struct item *item = buffer[head];

    produce_item(item);

    smp_wmb(); /* commit the item before incrementing the head */

    buffer->head = (head + 1) & (buffer->size - 1);

    /* wake_up() will make sure that the head is committed before
     * waking anyone up */
    wake_up(consumer);
}

spin_unlock(&producer_lock);
Run Code Online (Sandbox Code Playgroud)

问题:

  1. 由于此代码显式处理内存排序和原子性,spin_lock()的重点是什么?
  2. 到目前为止,我的理解是ACCESS_ONCE停止编译器重新排序,是吗?
  3. produce_item(item)是否只发出与该项关联的所有写入操作?
  4. 我相信smp_wmb()保证produce_item(item)中的所有写入都在它之后的"发布"写入之前完成.真正?
  5. 我获得此代码的页面上的注释似乎暗示在更新头索引后通常需要smp_wmb(),但wake_up(消费者)执行此操作,因此没有必要.真的吗?如果是这样的话? …

linux concurrency circular-buffer memory-barriers

9
推荐指数
1
解决办法
1万
查看次数

没有优先级倒置的环形缓冲区

我有一个需要将数据传递给低优先级进程的高优先级进程.我写了一个基本的环形缓冲区来处理数据的传递:

class RingBuffer {
  public:
    RingBuffer(int size);
    ~RingBuffer();

    int count() {return (size + end - start) % size;}

    void write(char *data, int bytes) {
      // some work that uses only buffer and end
      end = (end + bytes) % size;
    }

    void read(char *data, int bytes) {
      // some work that uses only buffer and start
      start = (start + bytes) % size;
    }

  private:
    char *buffer;
    const int size;
    int start, end;
};
Run Code Online (Sandbox Code Playgroud)

这是问题所在.假设低优先级进程有一个oracle,它确切地告诉它需要读取多少数据,因此count()永远不需要调用.然后(除非我遗漏了什么)没有并发问题.但是,只要低优先级线程需要调用count()(高优先级线程可能也想调用它来检查缓冲区是否太满),count()或更新中的数学可能会结束不是原子的,引入了一个bug.

我可以在访问周围放置一个互斥体来开始和结束但如果高优先级线程必须等待低优先级线程获取的锁定,那么这将导致优先级倒置. …

c++ concurrency circular-buffer

8
推荐指数
1
解决办法
1189
查看次数

C中的循环缓冲区实现

我找到了关于如何实现循环缓冲区的伪代码.

// Producer.
while (true) {
  /* produce item v */
  while ((in+1)%n == out)
    /* Wait. */;
  b[in] = v;
  in = (in + 1) % n
}

// Consumer.
while (true) {
  while (in == out)
    /* Wait. */;
  w = b[out];
  out = (out + 1) % n;
  /* Consume item w. */
}
Run Code Online (Sandbox Code Playgroud)

我不明白的是"消费项目w".评论,因为我认为w = b[out];我们正在消费w,不是吗?

c circular-buffer data-structures

8
推荐指数
1
解决办法
2879
查看次数

高效的循环清单

我想要一个简单而有效的循环缓冲区/队列.如果我使用std::vector,我必须这样做:

if ( v.size() >= limit ) {
    std::vector<int> it = v.begin();
    v.insert( it, data );
    v.erase( it+1 );
}
Run Code Online (Sandbox Code Playgroud)

有没有更简单的解决方案?

c++ vector circular-buffer circular-list

8
推荐指数
1
解决办法
3万
查看次数

为什么循环缓冲区在 C++ 中没有标准化?

我想知道循环缓冲区(循环队列或双端队列)标准化的历史。

AFAIK,当前的 C++ 标准(C++ 2023)在 STL 中没有提供循环缓冲区。我用 google 搜索了一下,只发现了一个提案,ring_span大约是在 2015 年。Boost 的circular_buffer. 有些提供内部实现,例如cqueue.

如果使用 a 重复推入和弹出操作std::deque,则会重复分配和释放堆块。在 Qt(最大的 C++ 项目之一)中,情况更糟,QQueue不断分配堆块(并且从不释放)。

我不是在征求意见。我想了解历史。我认为标准化循环缓冲区如此困难有充分的理由。

c++ circular-buffer

8
推荐指数
0
解决办法
2555
查看次数

堆栈的替代品

我正在使用C#在.Net环境中工作.我需要一些替代堆栈数据结构.某种绑定堆栈.集合中元素的数量不应超过某个固定的指定数量.并且,如果实现了该数字并且推送了新元素,则必须删除大多数旧元素.我需要这个来存储撤消/重做策略的命令.

.net c# stack circular-buffer data-structures

7
推荐指数
2
解决办法
881
查看次数

如何在iOS项目中实现CHCircularBuffer?

对于我的游戏iOS项目,我需要一个环形缓冲区.它应该类似于一个队列,其中元素输出并进入,但缓冲区中元素的总量应保持不变.

我使用java成功实现了环形缓冲区,但我不熟悉objective-c.我在网上找到了一个名为CHCircularBuffer的环形缓冲区实现:https://bitbucket.org/devartum/chdatastructures/src/4d6d7194ee94/source/CHCircularBuffer.m 但是我没能正确实现它.

循环缓冲区是名为TerrainManager的类的属性,它可以生成所有数学地形.

@interface TerrainManager : NSObject{

    int terrainParts;

    CHCircularBuffer* circularTerrainBuffer;
}

@property(nonatomic, retain) CHCircularBuffer *circularTerrainBuffer;
@end
Run Code Online (Sandbox Code Playgroud)

这是如何在TerrainManager的实现中初始化环形缓冲区

circularTerrainBuffer = [[CHCircularBuffer alloc] initWithCapacity:parts];
Run Code Online (Sandbox Code Playgroud)

这将创建缓冲区的实例,并将size属性设置为parts.现在我使用addObject方法将对象添加到缓冲区:

[circularTerrainBuffer addObject:[NSNumber numberWithDouble:0.2]];
Run Code Online (Sandbox Code Playgroud)

有时这行会收到错误"exec_bad_access".例如,当我初始化容量为15的缓冲区时,一切都很好,20我得到了错误.

我现在尝试从绘图发生的terrain类访问缓冲区.但每当我尝试访问对象时,我都会收到"bad_access"错误.

NSArray *arr = [terrainManager.circularTerrainBuffer allObjects];
Run Code Online (Sandbox Code Playgroud)

例如,这一行会产生错误.

所以我的代码有问题.也许我不理解缓冲区并以错误的方式添加对象.我不知道.任何想法或建议?

objective-c circular-buffer chdatastructures

7
推荐指数
1
解决办法
2024
查看次数

循环队列的缺点?

最近,在一次采访中我被问到使用循环队列的缺点.我什么都想不到.在互联网上搜索我发现的唯一答案是它比线性队列更难实现:).还有其他缺点吗?

language-agnostic queue circular-buffer data-structures

7
推荐指数
1
解决办法
1万
查看次数

C++ std :: deque实现:为什么不使用循环缓冲区?

我对deque的实现进行了一些搜索.根据这篇文章,deque使用向量的向量.我知道在开始和结束时推送应该是恒定的时间,并且还需要随机访问.我认为循环缓冲区满足所有这些要求,并且更加简单.那么为什么不使用循环缓冲区?

我还发现了增强循环缓冲区.它与deque相比如何?


编辑:好的,所以它与迭代器失效规则有关.它指出:

所有迭代器和引用都是无效的,除非插入的成员位于双端队列的末尾(前面或后面)(在这种情况下,所有迭代器都无效,但对元素的引用不受影响)

我的理解是重载像iter ++这样的运算符,迭代器必须拥有一个指向节点映射的指针和一个指向块的指针,所以如果重新分配节点映射,迭代器就会失效.但由于数据从未移动,因此引用仍然有效.

c++ stl circular-buffer deque

7
推荐指数
1
解决办法
3890
查看次数