`
shake863
  • 浏览: 664463 次
  • 性别: 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);
}

 

 

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

分享到:
评论

相关推荐

    labview 环形缓冲区组件

    1. 创建环形缓冲区:在LabVIEW中,可以通过添加“环形缓冲区”控件来创建一个环形缓冲区。设定缓冲区的大小(即可以存储的最大数据项数)和数据类型。 2. 写入数据:将实时采集到的数据写入缓冲区。这通常通过调用...

    环形缓冲区实现原理

    环形缓冲区是一种在计算机编程中广泛使用的数据结构,尤其在通信程序中扮演着重要角色。其基本原理是提供一个固定大小的存储空间用于数据的暂存,读取和写入操作分别由两个指针控制,读指针和写指针分别追踪下一个可...

    arrayBuffer(环形缓冲区)

    环形缓冲区(Circular Buffer),又称为循环缓冲区或环形队列,是一种常见的数据结构,广泛应用于数据传输、通信协议、实时系统等领域。在IT行业中,特别是在处理高并发、实时性要求高的数据流时,环形缓冲区因其...

    STM32进阶之串口环形缓冲区实现

    ### STM32进阶之串口环形缓冲区实现 #### 一、引言 在嵌入式系统开发中,串口通信是非常基础且重要的环节之一。然而,在实际应用过程中,尤其是在数据量较大或数据传输速率较快的情况下,简单的串口中断接收发送...

    一个封装好的C++环形缓冲区

    ### 知识点详解:C++中的环形缓冲区实现 #### 1. 环形缓冲区概念 环形缓冲区(Circular Buffer),又称循环队列,是一种数据结构,通常用于实现高效的缓存机制。它在一个固定大小的数组中进行操作,当缓冲区满时,...

    无锁 环形缓冲区

    无锁环形缓冲区是一种在多线程编程中常见的数据结构,它被广泛应用于高效并发环境中的数据交换。无锁(Lock-Free)意味着在访问共享数据时,无需使用传统的锁机制来确保线程安全,而是依赖于原子操作(Atomic ...

    22. USART_CircleBuffer 串口接收环形缓冲区

    本文将深入探讨如何使用环形缓冲区(Circle Buffer)技术优化STM32的串口接收功能。 串口通信,全称通用异步收发传输器(Universal Asynchronous Receiver/Transmitter,UART),是一种简单但实用的串行通信协议,...

    环形缓冲区建立源码下载

    环形缓冲区(Circular Buffer),又称为循环缓冲区或环形队列,是计算机科学中一种常见的数据结构,尤其在实时系统和多线程通信中应用广泛。它是一种利用有限空间进行高效数据存储和读取的数据结构,其设计思想是将...

    环形缓冲区源代码

    环形缓冲区是一种高效的数据结构,常用于实时系统和通信协议中,如串口通讯。在串口通信中,接收端需要一个数据容器来暂存接收到的数据,而环形缓冲区正好能满足这一需求,因为它提供了高效的数据存取机制。 环形...

    环形缓冲测试.rar

    STM32F103ZET6芯片,配置串口,创建环形缓冲,通过串口收发,可以做到无丢包,STM32F103ZET6芯片,配置串口,创建环形缓冲,通过串口收发,可以做到无丢包,STM32F103ZET6芯片,配置串口,创建环形缓冲,通过串口...

    环形缓冲器在频发事件中的应用

    环形缓冲器在频发事件中的应用:深入解析与实践 在现代电子设备与系统设计中,单片机(MCU)的应用日益广泛,尤其是在工业控制、消费电子、汽车电子等领域。然而,随着应用场景的复杂性和实时性要求的提高,单片机...

    C语言环形缓冲区

    环形缓冲区是一种高效的数据通信和数据存储结构,在C语言编程中经常被用来解决多线程环境中的数据共享问题。它的设计灵感来源于计算机内存管理中的“缓冲”概念,通过一个固定大小的数组来实现,数据在缓冲区中循环...

    STM32 环形缓冲

    STM32环形缓冲是一种在嵌入式系统中常见的数据处理技术,特别是在串口通信中,它被广泛应用于上位机与下位机之间的数据交换。环形缓冲的设计原理是利用数组的循环特性,实现数据的高效存储和读取。在STM32微控制器中...

    Delphi实现的环形缓冲区(全文件)

    环形缓冲区是一种在计算机编程中常见的数据结构,特别是在实时系统和并发编程中。它以一个固定大小的数组为基础,通过巧妙地管理读写指针,实现数据的先进先出(FIFO)处理。在Delphi中实现环形缓冲区,我们可以充分...

    环形缓冲区 封装模板类

    功 能:环形缓冲区 优 点:相对于队列来说减少了很多对地址的反复操作,增加稳定性。 作 者:XadillaX Q Q:8644325 说 明: | 构造: CircleBuffer&lt;类型名&gt; //构造时可选参数环形缓冲区大小,默认65535个元素 | ...

    Delphi实现的环形缓冲区

    环形缓冲区(Circular Buffer)是一种在内存管理中常见的数据结构,它被广泛应用于各种实时系统、通信协议和数据采集系统中。在Delphi编程环境中,实现环形缓冲区可以帮助开发者高效地处理数据流,避免数据丢失并...

    基于STM32FxUART数据传输环形缓冲区实现

    本项目重点在于基于STM32F系列(具体为STM32Fx)的UART(通用异步收发传输器)数据传输,通过环形缓冲区的实现来优化通信效率。下面将详细解释这一技术及其应用。 首先,**UART** 是微控制器与外界进行串行通信的...

    环形缓冲区读写操作的分析与实现

    ### 环形缓冲区读写操作的分析与实现 #### 引言 环形缓冲区作为嵌入式系统中的重要数据结构,在多任务环境中扮演着关键角色。它能够有效地管理数据流,尤其是在存在单一读任务和单一写任务的情况下。通过采取适当...

    电子-stm32f10xdemo环形缓冲区.rar

    STM32F10X Demo中的环形缓冲区是一个关键的软件设计概念,它在单片机和嵌入式系统编程中广泛使用。环形缓冲区(也称为循环缓冲区或双端队列)是一种高效的数据结构,允许数据在固定大小的内存块中无缝流动,实现了...

Global site tag (gtag.js) - Google Analytics