Queue
来源:互联网 发布:随机数预测算法 编辑:程序博客网 时间:2024/06/12 13:29
typedef struct __struct_queue__ TQueue;
struct __struct_queue__
{
void** buffer;
uint32_t capacity;
uint32_t wr;
uint32_t rd;
pthread_mutex_t mutex;
pthread_cond_t cond_full;
pthread_cond_t cond_empty;
uint32_t enable_print;
};
/**
* Default queue configuration.
*/
static const TQueue QUEUE_INITIALIZER =
{
.buffer = NULL,
.capacity = 0,
.wr = 0,
.rd = 0,
.mutex = PTHREAD_MUTEX_INITIALIZER,
.cond_empty = PTHREAD_COND_INITIALIZER,
.cond_full = PTHREAD_COND_INITIALIZER,
.enable_print=0,
};
/**
* Check if the queue is full
* @param queue queue
* @return true if full, false if not.
*/
bool Queue_IsFull(TQueue * queue)
{
return (((queue->wr-queue->rd) % queue->capacity) == queue->capacity-1) ? true : false;
}
/**
* Check if the queue is empty
* @param queue queue
* @return true if empty, false if not.
*/
bool Queue_IsEmpty(TQueue * queue)
{
if(queue->enable_print)printf("IsEmpty=%s %d %d %d %d\n",
(0 == ((queue->rd-queue->wr)%queue->capacity)) ? "true":"false",
((queue->rd-queue->wr)%queue->capacity),
queue->rd,queue->wr,queue->capacity);
return (0 == ((queue->rd-queue->wr)%queue->capacity)) ? true:false;
}
/**
* Push the value into the queue.
* @param queue queue
* @param value value will be put into the queue
*/
void Queue_Enqueue(TQueue *queue, void *value)
{
bool empty_flag=false;
// Lock the queue
pthread_mutex_lock(&(queue->mutex));
// Wait for the queue to be not full
while (true==Queue_IsFull(queue))
{
if(queue->enable_print)
printf("\nFull\n");
pthread_cond_wait(&(queue->cond_full), &(queue->mutex));
}
// Push the value into queue.
//~ if(Queue_IsEmpty(queue))
empty_flag=Queue_IsEmpty(queue);
queue->buffer[queue->wr % queue->capacity] = value;
queue->wr++;
pthread_mutex_unlock(&(queue->mutex));
if(true==empty_flag)
{
if(queue->enable_print)
printf("\nBroadCast Enqueue\n");
pthread_cond_broadcast(&(queue->cond_empty));
}
}
/**
* Enqueue in non-block mode.
* @param queue queue
* @param value value that will be enqueued
* @return true if enqueued, false if not
*/
bool Queue_TryEnqueue(TQueue *queue, void *value)
{
bool ret=false,empty_flag;
pthread_mutex_lock(&(queue->mutex));
if(false == Queue_IsFull(queue))
{
empty_flag=Queue_IsEmpty(queue);
queue->buffer[queue->wr % queue->capacity] = value;
queue->wr++;
ret = true;
}
pthread_mutex_unlock(&(queue->mutex));
if(ret==true&&true==empty_flag)
{
pthread_cond_broadcast(&(queue->cond_empty));
}
return ret;
}
/**
* Dequeue from queue in block mode. If no message in the queue, function will be blocked
* until there is a message returned.
* @param queue queue.
*/
void *Queue_Dequeue(TQueue *queue)
{
bool full_flag;
pthread_mutex_lock(&(queue->mutex));
// Wait for message in queue.
while(Queue_IsEmpty(queue))
{
if(queue->enable_print)printf("IsEmpty=%s %d %d %d %d\n",
(0 == ((queue->rd-queue->wr)%queue->capacity)) ? "true":"false",
((queue->rd-queue->wr)%queue->capacity),
queue->rd,queue->wr,queue->capacity);
pthread_cond_wait(&(queue->cond_empty), &(queue->mutex));
}
full_flag=Queue_IsFull(queue);
void *value = queue->buffer[queue->rd % queue->capacity];
queue->rd++;
pthread_mutex_unlock(&(queue->mutex));
if(true==full_flag)
pthread_cond_broadcast(&(queue->cond_full));
return value;
}
/**
* Dequeue in non-block mode.
* @param queue queue
*/
bool Queue_TryDequeue(TQueue *queue,void** ret)
{
// void * ret = NULL;
bool is_valid=false,full_flag;
pthread_mutex_lock(&(queue->mutex));
// If there is message in queue, dequeue.
if(false == Queue_IsEmpty(queue))
{
full_flag=Queue_IsFull(queue);
*ret = queue->buffer[queue->rd % queue->capacity];
queue->rd++;
is_valid=true;
}
pthread_mutex_unlock(&(queue->mutex));
if (true== is_valid&&true==full_flag)
{
pthread_cond_broadcast(&(queue->cond_full));
}
return is_valid;
}
/**
* Get the element count in queue.
* @param queue queue
* @return element count in queue
*/
int Queue_Sizeof(TQueue *queue)
{
pthread_mutex_lock(&(queue->mutex));
int size = (queue->rd-queue->wr)%queue->capacity;
pthread_mutex_unlock(&(queue->mutex));
return size;
}
/**
* Create a queue.
* @param capacity capacity of the queue.
* @return queue handle
*/
TQueue *Queue_Create(uint32_t capacity)
{
TQueue *q = (TQueue*)malloc(sizeof(TQueue));
if(NULL != q)
{
*q = QUEUE_INITIALIZER;
capacity += 1;
q->buffer = (void **)malloc(sizeof(void*)*(capacity));
if(NULL == q->buffer)
{
free(q);
return NULL;
}
q->capacity=capacity;
}
return q;
}
/**
* Destroy the queue.
* @param queue
* @param item_free
*/
void Queue_Destroy(TQueue *queue, void (*item_free)(void *))
{
void *item;
do
{
if(Queue_IsEmpty(queue))
break;
item = Queue_Dequeue(queue);
if(NULL!=item_free)
item_free(item);
}while(NULL != item);
free(queue->buffer);
free(queue);
}
void Queue_EnableDebug(TQueue *q)
{
q->enable_print=1;
}
- Queue
- queue
- Queue
- QUEUE ~
- queue
- queue
- queue
- queue
- queue
- queue
- Queue
- Queue
- queue
- queue
- Queue
- Queue
- queue
- Queue
- linux下升级tomcat中的应用服务器
- [LeetCode]-012-Integer to Roman
- soot
- Windows中
- VS 常用调试快捷键
- Queue
- trie树(字典树)
- 浅谈java及应用
- 将数字字符串转化为数字
- Hdfs/代码总结
- 求取圆形区域内的平均灰度值
- maven编译java web工程
- 我使用过的Linux命令之iconv - 字符编码转换工具
- css控制UL LI 的样式详解