`
shake863
  • 浏览: 637322 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

环形缓冲

阅读更多
/**
 * 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);
}

 

 

   见到的一个不错的环形缓冲。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics