buffer(缓冲区模式)
来源:互联网 发布:css是什么软件 编辑:程序博客网 时间:2024/05/01 23:01
1、定义:
将消息封装成一个对象,发送端将其存储到一个缓冲区中,接收端从缓冲区中取消息。
2、结构图:
3、协作角色:
略
4、适用性:
1、发送端和接收端不能同步
2、要对发送对象进行优化,排序等特殊处理
5、实例:
1、需求,发送任务和接受任务不能同步,
2、实现:
msg_queue.h
#ifndef __MSG_QUEUE_H__#define __MSG_QUEUE_H__#define QUEUE_DATA_MAX_LEN64typedef struct qelem_s {char *data[QUEUE_DATA_MAX_LEN];struct qelem_s *next;}qelem_t;typedef struct queue_s {qelem_t *first;qelem_t *last;unsigned int nelem;unsigned int max;pthread_mutex_t mutex;}queue_t;#define RET_SUCCESS0#define RET_FAIL(-1)int msg_queue_init();int msg_queue_create(unsigned int *qid);int msg_queue_destroy(unsigned int qid);int msg_queue_add(unsigned int qid, void *data, int size);int msg_queue_del(unsigned int qid, void *data, int size);int msg_queue_num(unsigned int qid, unsigned int *num);#endif
msg_queue.c
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <pthread.h>#include "msg_queue.h"#define QUEUE_MAX_NUM3#define QUEUE_MAX_LEN16struct msg_queue_s {queue_t *queue[QUEUE_MAX_NUM];int used[QUEUE_MAX_NUM];pthread_mutex_t queue_lock;};struct msg_queue_s msg_queue;int msg_queue_init(){memset((void *)&msg_queue, 0, sizeof(msg_queue));pthread_mutex_init(&msg_queue.queue_lock, NULL);return RET_SUCCESS;}int msg_queue_create(unsigned int *qid){unsigned int i,j;int ret;qelem_t *new;qelem_t *cur;pthread_mutex_lock(&msg_queue.queue_lock);for(i = 0; i < QUEUE_MAX_NUM; i++){if(0 == msg_queue.used[i]){break;}}if(i == QUEUE_MAX_NUM){pthread_mutex_unlock(&msg_queue.queue_lock);return RET_FAIL;}printf("%s %d\n",__func__, __LINE__);msg_queue.queue[i] = (queue_t *)malloc(sizeof(queue_t));if(!msg_queue.queue){pthread_mutex_unlock(&msg_queue.queue_lock);return RET_FAIL;}ret = pthread_mutex_init(&msg_queue.queue[i]->mutex, NULL);if(ret != 0){free(msg_queue.queue[i]);pthread_mutex_unlock(&msg_queue.queue_lock);return RET_FAIL;}msg_queue.queue[i]->first = (qelem_t *)malloc(sizeof(qelem_t));if(!msg_queue.queue[i]->first){free(msg_queue.queue[i]);pthread_mutex_unlock(&msg_queue.queue_lock);return RET_FAIL;}memset(msg_queue.queue[i]->first, 0, sizeof(qelem_t));cur = msg_queue.queue[i]->last = msg_queue.queue[i]->first;msg_queue.queue[i]->nelem = 0;msg_queue.queue[i]->max = QUEUE_MAX_LEN - 2;for(j = 0; j < QUEUE_MAX_LEN -2; j++){new = (qelem_t *)malloc(sizeof(qelem_t));if(!new){while(msg_queue.queue[i]->first){cur = msg_queue.queue[i]->first->next;free(msg_queue.queue[i]->first);msg_queue.queue[i]->first = cur;}free(msg_queue.queue[i]);pthread_mutex_unlock(&msg_queue.queue_lock);return RET_FAIL;}memset(new, 0, sizeof(qelem_t));cur->next = new;cur = new;}cur->next = msg_queue.queue[i]->first;msg_queue.used[i] = 1;*qid = i;pthread_mutex_unlock(&msg_queue.queue_lock);return RET_SUCCESS;}int msg_queue_destroy(unsigned int qid){queue_t *queue;qelem_t *cur;if(qid >= QUEUE_MAX_NUM)return RET_FAIL;pthread_mutex_lock(&msg_queue.queue_lock);queue = msg_queue.queue[qid];while(msg_queue.queue[qid]->first){cur = queue ->first->next;free(queue ->first);queue ->first = cur;}pthread_mutex_destroy(&queue->mutex);free(queue);pthread_mutex_unlock(&msg_queue.queue_lock);return RET_SUCCESS;}int msg_queue_add(unsigned int qid, void *data, int size){if(qid >= QUEUE_MAX_NUM)return RET_FAIL;//printf("enter into %s %s %d qid %d\n",__func__,(char *)data,size,qid);queue_t *queue = msg_queue.queue[qid];pthread_mutex_lock(&queue->mutex);if(size > QUEUE_DATA_MAX_LEN)size = QUEUE_DATA_MAX_LEN;memcpy(queue->last->data, data,size);queue->last = queue->last->next;queue->nelem++;if(queue->nelem > queue->max){printf("this element cover the first one\n");queue->nelem = queue->max;}pthread_mutex_unlock(&queue->mutex);return RET_SUCCESS;}int msg_queue_del(unsigned int qid, void *data, int size){if(qid >= QUEUE_MAX_NUM)return RET_FAIL;queue_t *queue = msg_queue.queue[qid];pthread_mutex_lock(&queue->mutex);if(queue->nelem <= 0){pthread_mutex_unlock(&queue->mutex);return RET_FAIL;}if(size > QUEUE_DATA_MAX_LEN)size = QUEUE_DATA_MAX_LEN;memcpy(data, queue->first->data, size);memset(queue->first->data, 0, QUEUE_DATA_MAX_LEN);queue->first = queue->first->next;queue->nelem--;pthread_mutex_unlock(&queue->mutex);return RET_SUCCESS;}int msg_queue_num(unsigned int qid, unsigned int *num){if(qid >= QUEUE_MAX_NUM)return RET_FAIL;*num = msg_queue.queue[qid]->nelem;return RET_SUCCESS;}
msg_send.h
#ifndef __MSG_SEND_H__#define __MSG_SEND_H__void* send_task(void *args);#endif
msg_send.c
#include <stdio.h>#include <string.h>#include <stdlib.h>#include "msg_send.h"#include "msg_queue.h"void* send_task(void *args){int ret;char buf[QUEUE_DATA_MAX_LEN];unsigned int qid = *((int *)args);int count = 0;while(1){//printf("input string and len < %d:\n",QUEUE_DATA_MAX_LEN);memset(buf, 0 , sizeof(buf));//scanf("%s",&buf);sprintf(buf, "msg %d",count);ret = msg_queue_add(qid, buf, strlen(buf));count++;sleep(1);}}
msg_receive.h
#ifndef __MSG_RECEIVE_H__#define__MSG_RECEIVE_H__void* receive_task(void *agrs);#endif
msg_receive.c
#include <stdio.h>#include <string.h>#include <stdlib.h>#include "msg_queue.h"#include "msg_receive.h"void* receive_task(void *args){int ret;char buf[QUEUE_DATA_MAX_LEN];unsigned int qid = *((int *)args);while(1){memset(buf, 0 , sizeof(buf));ret = msg_queue_del(qid, buf, QUEUE_DATA_MAX_LEN);if(ret == RET_SUCCESS)printf("msg is %s\n",buf);sleep(3);}}
client.c
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <pthread.h>#include "msg_queue.h"#include "msg_send.h"#include "msg_receive.h"int main(){pthread_t send, receive;unsigned int qid;int ret;void *status;msg_queue_init();ret = msg_queue_create(&qid);printf("qid is %d ret %d\n",qid,ret);ret = pthread_create(&send, NULL, send_task, &qid);if(ret != 0){printf("create send task err\n");return -1;}ret = pthread_create(&receive, NULL, receive_task, &qid);if(ret != 0){printf("create receive task err\n");//pthread_destory(&send);return -1;}pthread_join(send, &status);pthread_join(receive, &status);return 0;}
- buffer(缓冲区模式)
- Stencil Buffer(模板缓冲区)
- Stencil Buffer(模板缓冲区)
- Stencil Buffer(模板缓冲区)
- Stencil Buffer(模板缓冲区)
- 缓冲区 buffer
- 缓冲区(Buffer)
- Java NIO中的缓冲区Buffer(二)创建-复制缓冲区
- Java NIO中的缓冲区Buffer(二)创建-复制缓冲区
- Java NIO中的缓冲区Buffer(二)创建-复制缓冲区
- Java NIO中的缓冲区Buffer(二)创建-复制缓冲区
- Ring Buffer (circular Buffer)环形缓冲区简介(C++版本)
- 说说循环缓冲区(Ring Buffer)
- 阻塞I/O的缓冲区(Buffer)
- 圆形缓冲区(循环buffer)实现
- Java NIO —— Buffer(缓冲区)
- 【转】圆形缓冲区(循环buffer)实现
- NIO - Buffer缓冲区
- 如何指定tomcat的JDK -转
- JS往textarea的光标所在处添加文字+将光标移动到文字末尾
- 利用dom4j生成带dom的xml文件
- 查看存储过程文本中是否包含有该字符串--SQL脚本
- 苦逼的IT,什么时候是个头
- buffer(缓冲区模式)
- url encode decode
- 引用外部jar包,程序出错的解决方法
- 堆栈
- XML基础入门
- base 64编码
- 普及下视频处理整体流程
- Flash图表控件FusionCharts如何定制图表中的趋势线和趋势区
- arm-linux-gcc的下载及安装