/**
* Copyright (c) 2008, ×××研发中心
* All rights reserved.
*
* 名 称:
* 摘 要:
* 作 者:test * 版 本:1.0
* 时 间:08.08.27 16:21:55
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <pthread.h>
#include <time.h>
#define INITBUFSIZE 10 /*环型缓冲区初始单元个数*/
#define UNITSIZE 200/*每单元大小*/
using namespace std;
/*global data*/
/*Cirbuf chain 写进程可能很快 以至于不只有1个或2个环形缓冲,可能有多个*/
struct Cirbuf* packetCirbuf;
/*环形缓冲的一个单元*/
struct CirUnit
{
int flag; /*0 表明可写,1表明可读*/
char unit[UNITSIZE];
};
/*环形缓冲*/
struct Cirbuf
{
struct Cirbuf * newBuf; /*point to new Cirbuf*/
int readPoint; /*for reading thread*/
int writePoint; /*for writing thread*/
int bufSize; /*buf char array's size*/
struct CirUnit *buf; /*point to unit array*/
};
struct Cirbuf* GetNewCirbuf(int bufSize,struct Cirbuf* oldBuf)
{
if(bufSize>30000)
{
printf("oh my god,the bufSize is out of my league,I cannot handle it,exit");
exit(1);
}
struct Cirbuf* newBuf = new Cirbuf();
printf("new buffer %d\n",bufSize);
usleep(1000000);
if(oldBuf != NULL)
oldBuf->newBuf = newBuf;
newBuf->newBuf = NULL;
newBuf->readPoint = newBuf->writePoint = 0;
newBuf->bufSize = bufSize;
newBuf->buf = new CirUnit[bufSize];
memset(newBuf->buf,0,sizeof(CirUnit)*bufSize); /*初始化单元为0*/
return newBuf;
}
int FreeCirbuf(struct Cirbuf* bufPoint)
{
delete bufPoint->buf;
delete bufPoint;
printf("delete buffer \n");
return 1;
}
void DoWrite(struct Cirbuf* latestBuf,char flag)
{
latestBuf->buf[latestBuf->writePoint].unit[0] = flag;
printf("write %d \n",flag);
}
void DoRead()
{
printf("read %d \n",packetCirbuf->buf[packetCirbuf->readPoint].unit[0]);
}
extern "C" void* ReadThread(void *arg)
{
while(1)
{
usleep(200000);
if(packetCirbuf->buf[packetCirbuf->readPoint].flag == 0)
{
if(packetCirbuf->newBuf != NULL)
{
/*表明readthread已经处理完旧的缓冲区并且已经有新的缓冲区,这时应该释放旧缓冲*/
struct Cirbuf *temp = packetCirbuf;
packetCirbuf = packetCirbuf->newBuf;
FreeCirbuf(temp);
continue;
}
/* delay*/
pthread_cond_t mycond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER;
struct timespec ts;
int rv;
ts.tv_sec = 0;
ts.tv_nsec = 50000; /* 500,00 nanoseconds = 50 ms */
pthread_mutex_lock(&mymutex);
rv = pthread_cond_timedwait(&mycond, &mymutex, &ts);
pthread_mutex_unlock(&mymutex);
continue;
}
DoRead();
packetCirbuf->buf[packetCirbuf->readPoint].flag = 0;
if(++packetCirbuf->readPoint == packetCirbuf->bufSize)
packetCirbuf->readPoint = 0;
}
return NULL;
}
extern "C" void* WriteThread(void *arg)
{
struct Cirbuf* latestBuf;
/*进写进程后,初始化latestBuf指针 使其指向packetCirbuf,这时的packetCirbuf是由主线程函数创建的初始buf*/
latestBuf = packetCirbuf;
if(latestBuf == NULL)
{
cout << "packet capture buffer NULL error" << endl;
exit(0);
}
/*进入循环*/
char test=0;
while(1)
{
usleep(100000);
if (latestBuf->buf[latestBuf->writePoint].flag == 1)
{
/*we need a larger buf*/
latestBuf = GetNewCirbuf(latestBuf->bufSize * 2,latestBuf);
}
else
{
DoWrite(latestBuf,test++);
latestBuf->buf[latestBuf->writePoint].flag = 1;
if(++latestBuf->writePoint == latestBuf->bufSize)
latestBuf->writePoint = 0;
}
if(test == 127)
break;
}
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t threadNum[2];
packetCirbuf = GetNewCirbuf(INITBUFSIZE,NULL);
pthread_create(&threadNum[0],NULL,WriteThread,NULL);
pthread_create(&threadNum[1],NULL,ReadThread,NULL);
pthread_join(threadNum[0],NULL);
pthread_join(threadNum[1],NULL);
FreeCirbuf(packetCirbuf);
}
见到的一个不错的环形缓冲。