在不同的系統之間交換資料時,往往由于兩個系統時間不能完全同步。
為了保證生産者和消費者的同步,需要使用環形緩沖區。生産者以某一速度存入資料,消費者以某一速度取出資料,兩者的速度不用時刻一緻,但總體的平均速度必須相等!
以下是具體實作:
/**************FIFO Begin**************************************************/
/*溢出标志:0-正常,-1-溢出*/
#define FLAGS_OVERRUN 0x0001
/*
buf- 緩沖區位址
size- 大小
free- 空餘容量
putP- 下一個資料寫入位置
getP- 下一個資料獨處位置
*/
struct FIFO8{
char *buf;
int putP,getP,size,free,flags;
pthread_mutex_t mutex;
};
int fifo8_init(struct FIFO8 *fifo,int size);
int fifo8_put(struct FIFO8 *fifo, char data); //not mutiply thread safe
int fifo8_get(struct FIFO8 *fifo); //not mutiply thread safe
void fifo8_status(struct FIFO8 *fifo,int *len);
void fifo8_free(struct FIFO8 *fifo,int *len);
int fifo8_write(struct FIFO8 *fifo,char *data,int len);
int fifo8_read(struct FIFO8 *fifo,char *data,int len);
/*初始化*/
int fifo8_init(struct FIFO8 *fifo,int size) {
int ret=0;
fifo->flags=0;
fifo->free=size;
fifo->size=size;
fifo->putP=0;
fifo->getP=0;
fifo->buf=(char *)malloc(size);
if(fifo->buf==NULL){
LOGI("malloc fifo buffer failed!\n");
return -1;
}
ret = pthread_mutex_init(&(fifo->mutex),NULL);
if(ret <0){
LOGI("init mutex failed!\n");
return -1;
}
return 0;
}
/*向FIFO 中寫入1個資料 */
int fifo8_putPut(struct FIFO8 *fifo, char data) {
if(fifo->free==0){
fifo->flags |= FLAGS_OVERRUN;
return -1;
}
fifo->buf[fifo->putP] = data;
fifo->putP++;
//循環隊列緩沖區
if(fifo->putP == fifo->size){
fifo->putP = 0;
}
fifo->free--;
return 0;
}
/*從FIFO 中取出一個資料 */
int fifo8_get(struct FIFO8 *fifo) {
int data;
if(fifo->free == fifo->size){
return -1;
}
data = fifo->buf[fifo->getP++];
//fifo->getP++;
if(fifo->getP == fifo->size){//用來實作循環
fifo->getP = 0;
}
fifo->free++;
return data;
}
/*寫入len個位元組,傳回寫入的位元組數*/
int fifo8_write(struct FIFO8 *fifo,char *data,int len){
int i=0;
pthread_mutex_lock(&(fifo->mutex));
if(fifo->free < len) {
pthread_mutex_unlock(&(fifo->mutex));
LOGI("the free size in not enough!\n");
return 0;
}
else {
LOGI("current fifo->putP =%d \n",fifo->putP);
for(i=0;i<len;i++){
fifo->buf[fifo->putP++] = *(data+i);
//循環隊列緩沖區
if(fifo->putP == fifo->size){
fifo->putP = 0;
}
fifo->free--;
}
}
pthread_mutex_unlock(&(fifo->mutex));
return len;
}
/*讀出len個位元組,傳回讀出的位元組數*/
int fifo8_read(struct FIFO8 *fifo,char *data,int len){
int i=0;
pthread_mutex_lock(&(fifo->mutex));
if(fifo->size!=fifo->free){
LOGI("current fifo->getP =%d \n",fifo->getP);
for(i=0; ; i++){
*(data+i) =fifo->buf[fifo->getP++];
if(fifo->getP == fifo->size){//用來實作循環
fifo->getP = 0;
}
fifo->free++;
if(fifo->size==fifo->free){
LOGI("the buffer is no data left!\n");
pthread_mutex_unlock(&(fifo->mutex));
return i+1;
}
if(i+1==len){
LOGI("read data finish!\n");
break;
}
}
}
else{
LOGI("the buffer is empty!\n");
pthread_mutex_unlock(&(fifo->mutex));
return 0;
}
pthread_mutex_unlock(&(fifo->mutex));
return len;
}
/*緩沖區被使用容量*/
void fifo8_status(struct FIFO8 *fifo,int *used) {
pthread_mutex_lock(&(fifo->mutex));
*used = fifo->size - fifo->free;
pthread_mutex_unlock(&(fifo->mutex));
}
/*緩沖區剩餘容量*/
void fifo8_free(struct FIFO8 *fifo ,int *free) {
pthread_mutex_lock(&(fifo->mutex));
*free = fifo->free;
pthread_mutex_unlock(&(fifo->mutex));
}