在实际应用中,环形队列通常用在只能buffer固定大小数据量的场景,如audio driver.
在buffer数据时,有一个writePointer来记录上层app往buffer写的位置,用一个readPointer来记录audio driver读的位置。
#include <string.h>
#include <stdio.h>
#define RING_BUF_SIZE 10
typedef struct _RingBuffer{
int _data[RING_BUF_SIZE];
int _writePointer;
int _readPointer;
int _size;
}RingBuffer;
void ringBuffer_init(RingBuffer *pRingBuffer)
{
memset(pRingBuffer->_data, 0 ,sizeof(pRingBuffer->_data));
pRingBuffer->_writePointer = 0;
pRingBuffer->_readPointer = 0;
pRingBuffer->_size = 0;
}
void ringBuffer_write(RingBuffer *pRingBuffer, int *data, int len)
{
if (pRingBuffer->_size + len > RING_BUF_SIZE)
{
printf("ring buffer full
");
return ;
}
int newWritePointer = 0;
int loop = 0;
newWritePointer = pRingBuffer->_writePointer + len;
if (newWritePointer >= RING_BUF_SIZE)
{
newWritePointer -= RING_BUF_SIZE;
loop = 1;
}
if (loop)
{
memcpy(pRingBuffer->_data + pRingBuffer->_writePointer, data, (RING_BUF_SIZE - pRingBuffer->_writePointer)*sizeof(int));
memcpy(pRingBuffer->_data, data + RING_BUF_SIZE - pRingBuffer->_writePointer, (len - (RING_BUF_SIZE - pRingBuffer->_writePointer))*sizeof(int));
}
else
{
memcpy(pRingBuffer->_data + pRingBuffer->_writePointer, data, len*sizeof(int));
}
pRingBuffer->_size += len;
pRingBuffer->_writePointer = newWritePointer;
}
void ringBuffer_read(RingBuffer *pRingBuffer, int *data, int len)
{
if (len > pRingBuffer->_size)
{
printf("no enough data
");
return;
}
int newReadPointer = 0;
int loop = 0;
newReadPointer = pRingBuffer->_readPointer + len;
if (newReadPointer >= RING_BUF_SIZE)
{
newReadPointer -= RING_BUF_SIZE;
loop = 1;
}
if (loop)
{
memcpy(data, pRingBuffer->_data + pRingBuffer->_readPointer,(RING_BUF_SIZE - pRingBuffer->_readPointer)*sizeof(int));
memcpy(data + RING_BUF_SIZE - pRingBuffer->_readPointer, pRingBuffer->_data, (len - (RING_BUF_SIZE - pRingBuffer->_readPointer))*sizeof(int));
}
else
{
memcpy(data, pRingBuffer->_data + pRingBuffer->_readPointer, len * sizeof(int));
}
pRingBuffer->_size -= len;
pRingBuffer->_readPointer = newReadPointer;
}
int main(int argc, char **argv)
{
int writeData1[6] = {0,1,2,3,4,5};
int writeData2[6] = {6,7,8,9,10,11};
int readData[4];
RingBuffer _ringBuffer;
ringBuffer_init(&_ringBuffer);
ringBuffer_write(&_ringBuffer, writeData1, 6);
printf("wp:%d, rp:%d, sz:%d
", _ringBuffer._writePointer, _ringBuffer._readPointer, _ringBuffer._size);
int idx = 0;
for (idx = _ringBuffer._readPointer; idx < _ringBuffer._writePointer; idx++)
{
printf("data after write:%d
", _ringBuffer._data[idx]);
}
ringBuffer_read(&_ringBuffer, readData, 4);
for (idx = _ringBuffer._readPointer; idx < _ringBuffer._writePointer; idx++)
{
printf("data after read:%d
", _ringBuffer._data[idx]);
}
printf("wp:%d, rp:%d, sz:%d
", _ringBuffer._writePointer, _ringBuffer._readPointer, _ringBuffer._size);
for (idx = 0; idx < 4; idx++)
{
printf("read data:%d
", readData[idx]);
}
ringBuffer_write(&_ringBuffer, writeData2, 6);
printf("wp:%d, rp:%d, sz:%d
", _ringBuffer._writePointer, _ringBuffer._readPointer, _ringBuffer._size);
for (idx = _ringBuffer._readPointer; idx < RING_BUF_SIZE; idx++)
{
printf("data after write:%d
", _ringBuffer._data[idx]);
}
for (idx = 0; idx < _ringBuffer._writePointer; idx++)
{
printf("data after write:%d
", _ringBuffer._data[idx]);
}
return 0;
}
运行结果如下: