Search Suggest

Ring buffer


1. Cấu trúc

2. Nguyên lý làm việc



3. Cách sử dụng

A single process/thread to process/thread buffer use case



Multiple processes/thread to process/thread use case



Single process/thread to multiple processes/thread use case




Single process/thread to multiple process/thread use case using a dispatcher and multiple queues


4. Source code sample
ringbufer.h
 #ifndef RINGBUFFER_H  
#define RINGBUFFER_H

#ifdef __cplusplus
extern "C" {
#endif

#include <stddef.h>
#include <stdbool.h>

/*
* ringbuffer.h - C ring buffer (FIFO) interface.
*/
typedef struct ringbuffer_t
{
void *buffer; // data buffer
void *buffer_end; // end of data buffer
size_t capacity; // maximum number of items in the buffer
size_t count; // number of items in the buffer
size_t sz; // size of each item in the buffer
void *head; // pointer to head
void *tail; // pointer to tail
} ringbuffer_t;

bool ring_init(ringbuffer_t *cb, size_t capacity, size_t sz);

bool ring_free(ringbuffer_t *cb);

bool ring_push_head(ringbuffer_t *cb, const void *item);

bool ring_pop_tail(ringbuffer_t *cb, void *item);

#ifdef __cplusplus
}
#endif

#endif /* RINGBUFFER_H */


ringbuffer.c
 #include "ringbuffer.h"  
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

bool ring_init(ringbuffer_t *cb, size_t capacity, size_t sz)
{
cb->buffer = malloc(capacity * sz);
if(cb->buffer == NULL){
printf("ring_init FAIL ! \n");
return false;
}

cb->buffer_end = (char *)cb->buffer + capacity * sz;
cb->capacity = capacity;
cb->count = 0;
cb->sz = sz;
cb->head = cb->buffer;
cb->tail = cb->buffer;
return true;
}

bool ring_free(ringbuffer_t *cb)
{
if(cb->buffer){
free(cb->buffer);
cb->buffer = NULL;
}else{
return false;
}
return true;
}

bool ring_push_head(ringbuffer_t *cb, const void *item)
{
if(cb->count == cb->capacity){
printf("Ringbuffer is Full ! \n");
return false;
}

memcpy(cb->head, item, cb->sz);
cb->head = (char*)cb->head + cb->sz;
if(cb->head == cb->buffer_end)
cb->head = cb->buffer;
cb->count++;

return true;
}

bool ring_pop_tail(ringbuffer_t *cb, void *item)
{
if(cb->count == 0){
printf("Ringbuffer is Empty ! \n");
return false;
}

memcpy(item, cb->tail, cb->sz);
cb->tail = (char*)cb->tail + cb->sz;
if(cb->tail == cb->buffer_end)
cb->tail = cb->buffer;
cb->count--;
return true;
}


ringbuffer_test.c
 #include <string.h>  
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "ringbuffer.h"

#define CAPACITY 10
typedef struct data_t{
int idata;
float fdata;
}data_t;

ringbuffer_t ringbf;


int main(int argc, char **argv)
{

ring_init(&ringbf, CAPACITY, sizeof(data_t));

int i;
data_t tmpdata;

for(i = 0; i < CAPACITY; i++){
tmpdata.idata = i;
tmpdata.fdata = i+1;
ring_push_head(&ringbf, (void*)&tmpdata);
printf("number of items: %d \n", ringbf.count);
}

for(i = 0; i < CAPACITY; i++){
ring_pop_tail(&ringbf, (void*)&tmpdata);

printf("number of items: %d, idata: %d, fdata: %f \n", ringbf.count, tmpdata.idata, tmpdata.fdata);

}

ring_free(&ringbf);
return 0;
}



Đăng nhận xét