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;}


 

 

 

 

 

 

 

 

原创粉丝点击