一、背景需求
應用場景是一個生產者一個消費者,兩者平均處理速度是相當的,但是有生產峯值速度太快,消費者處理速度跟不上的情況;
這種場景若用單線程處理,則會出現消費速度慢導致拖慢生產者的速度;
若使用雙線程處理,一個生產線程一個消費線程,這個時候就能用到隊列/環形隊列了。
二、相關知識
三、實現
int bufqueue_create(bufqueue_t *phead, size_t nmemb, size_t item_size)
{
int ix = 0;
if ( !phead ) {
return FAILURE;
}
#define __ISPOWER(_num_) ((_num_ ^ (_num_ - 1)) == (((_num_ - 1) << 1) + 1))
if ( !__ISPOWER(nmemb) ) {
return FAILURE;
}
/* Refree queue */
FREE_POINTER(phead->queue);
phead->queue = (bufqueue_item *)calloc(nmemb, sizeof(bufqueue_item));
if ( !phead->queue ) {
return FAILURE;
}
for ( ix = 0; ix < nmemb; ix++ ) {
phead->queue[ix].pitem = calloc(1, item_size);
if ( !phead->queue[ix].pitem ) {
return FAILURE;
}
}
phead->item_size = item_size;
phead->size = nmemb;
phead->mask = nmemb - 1;
phead->head = 0;
phead->tail = 0;
phead->used = 0;
printf("Queue alloc success, size: %zd ( Bytes )\n",
sizeof(bufqueue_t) + nmemb * item_size);
return SUCCESS;
}
void* bufqueue_tail(bufqueue_t *phead)
{
if ( SUCCESS == bufqueue_isfull(phead) ) {
return NULL;
}
return (phead->queue[phead->tail].pitem);
}
int bufqueue_push(bufqueue_t *phead)
{
phead->used++;
phead->tail = (phead->tail + 1) & phead->mask;
return SUCCESS;
}
void* bufqueue_pop(bufqueue_t *phead)
{
void *pitem = NULL;
if ( phead->tail == phead->head ) {
return NULL;
}
pitem = phead->queue[phead->head].pitem;
phead->head = (phead->head + 1) & phead->mask;
phead->used--;
return (pitem);
}
int bufqueue_isempty(bufqueue_t *phead)
{
if ( phead->tail == phead->head ) {
return SUCCESS;
}
return FAILURE;
}
int bufqueue_isfull(bufqueue_t *phead)
{
if ( !phead ) {
return FAILURE;
}
if ( phead->head == ((phead->tail + 1) & phead->mask) ) {
/* Queue is full */
return SUCCESS;
}
return FAILURE;
}