"Go" ring buffer

Source: Internet
Author: User

Original address: http://blog.csdn.net/linlinlinxi007/article/details/5086806

in communication programs, a ring buffer is often used as a data structure to hold the transmitted and received information in the communication. The ring buffer is a first-in, in-out loop buffer that provides mutually exclusive access to the buffer to the communication program.

1, the realization principle of ring buffer
A ring buffer usually has a read pointer and a write pointer. The read pointer points to the readable data in the ring buffer, and the write pointer points to the writable buffer in the ring buffer. By moving the read pointer and the write pointer, you can implement buffer data reading and writing. In general, the read user of the ring buffer only affects the read pointer, while the write user only affects the write pointer. If there is only one read user and one write user, then there is no need to add mutex protection mechanism to ensure the correctness of the data. If you have multiple read-write users accessing the ring buffer, you must add a mutex protection mechanism to ensure that multiple users have mutually exclusive access to the ring buffer.
Figure 1, Figure 2, and Figure 3 are the operations of a ring buffer. Figure 1 is the initial state of the ring buffer, you can see that both the read pointer and the write pointer point to the first buffer, Figure 2 is to add a data to the ring buffer after the case, you can see that the write pointer has been moved to the location of the data Block 2, and the read pointer is not moved; You can see that two data has been added to the ring buffer and a data has been read.

Server Common Component implementation----ring buffer


The issue of Message queue lock calls is solved, and the other one is probably too much memory allocation and release operations. Frequent memory allocations not only increase the overhead, but also cause more memory fragmentation, which is very detrimental to the long-term stable operation of our servers. Maybe we can use a memory pool, like the small memory allocator that comes with the SGI STL. But for this strict first-out order processing, the block size is not small, and the block size is not uniform memory allocation, more using a scheme called the ring buffer, mangos Network Code also has such a thing, its principle is relatively simple.
It is like two people around a round table in the chase, the runner is controlled by the network IO thread, when the data is written, the person will go forward, chasing the person is a logical thread, will continue to chase until the runner. What if we catch up? That is no data can be read, first wait, wait for the runner to run a few steps forward to chase, always can not let the game have no play. If the chasing people run too slow, the runners turn around and chase after the people? Let's have a rest, then. If you keep chasing the chase, you'll have to change to a faster runner, or the game can't be played.
In particular, we emphasize that the processing in strict FIFO order is a requirement that must be followed for the use of ring buffers. That is, everyone has to obey the rules, the chasing people can not cross the table from the past, the runners certainly do not allow the reverse run. As for why, do not need to explain more.
Ring buffers are a good technique, without the frequent allocation of memory, and in most cases, the repeated use of memory allows us to do more with fewer blocks of memory.
In the network IO thread, we will prepare a ring buffer for each connection to temporarily hold the received data to cope with half-pack and sticky packets(that is, the sender sends a packet of packets of data to the receiving party when it is received.)The situation. After unpacking and decryption is complete, we will copy this packet into the logical thread message queue, if we only use a queue, then this will also be a ring buffer, the IO thread is written in, the logical thread reads in the back, chasing each other. But if we use the optimization scheme described earlier, we may not need the ring buffer here, at least we don't need them to be ring-shaped anymore. Because we no longer read and write to the same queue, each queue is written to the logical thread to read, after the logical thread reads the empty queue and then to the IO thread to write, a fixed size buffer. It's okay, so good technology, it's going to be used somewhere else.

2. Example: implementation of ring buffer

The ring buffer is one of the most widely used data structures in data communication programs, and the following code implements a ring buffer:

1 /*ringbuf. C*/2#include<stdio. H>3#include<ctype. H>4 5 #defineNMAX 86 7 intIput =0;/*the current placement of the ring buffer*/8 intIget =0;/*the current fetch position of the buffer*/9 intn =0;/*total number of elements in the ring buffer*/Ten DoubleBuffer[nmax]; One  A /*the address number of the ring buffer calculates the function, and if it reaches the tail of the wake buffer, it goes back to the head. The valid address number for the ring buffer is: 0 to (NMAX-1)*/ - intAddring (inti) - { the      return(i+1) = = NMAX?0: i+1; - } -  - /*take an element from a ring buffer*/ + Double Get(void) - { +         intPos; A         if(n>0) at         { -Pos =Iget; -Iget =addring (iget); -n--; -              returnBuffer[pos]; -         } in         Else  -         { toprintf ("Buffer isempty/n "); +             return 0.0; -         }        the  } *  $ /*put an element into the ring buffer*/Panax Notoginseng voidPutDoublez) - { the         if(n<NMAX) +         { Abuffer[iput]=Z; theIput =addring (iput); +n++; -         } $         Else $printf ("Buffer isfull/n "); - } -  the   - Wuyi intmain{void) the { -Chat opera[5]; Wu         DoubleZ; -          Do  About         { $printf ("Please input p|g|e?")"); -scanf ("%s", &opera); -             Switch(ToLower (opera[0])) -             { A                     Case' P ':/*put*/ +printf ("Please input afloatNumber?"); thescanf ("%lf", &z); - put (z); $                         Break; the                      Case' G ':/*Get*/ thez =Get(); theprintf ("%8.2f  frombuffer/n ", z); the                          Break; -                      Case' E ': inprintf ("end/n "); the                          Break; the                     default: Aboutprintf ("%s-operation command error! /n ", opera); the}/*End Switch*/ the} while(opera[0] !=' e '); the         return 0; +}

"Go" ring buffer

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.