简介

ringbuffer是一个无锁的环行缓冲区,它适用于一个线程读和一个线程写的场景。
ringbuffer会维护两个指针:

读写指针是一直向前前进的,然后通过 取模 的方式,将读写指针映射到缓冲区上。并且读指针一定不大于写指针。


Python实现

class RingBuffer:
    def __init__(self, buffer_size):
        self._buffer_size = buffer_size
        self._list = [None] * buffer_size
        self._read_cursor = 0
        self._write_cursor = 0

    def full(self):
        return self._write_cursor - \
            self._read_cursor == self._buffer_size

    def append(self, element):
        if self.full():
            raise RuntimeError("ringbuffer is full")

        self._list[self._write_cursor % self._buffer_size] = element
        self._write_cursor = self._write_cursor + 1

    def empty(self):
        return self._write_cursor == self._read_cursor

    def pop(self):
        if self.empty():
            raise RuntimeError("ringbuffer is empty")
        result = self._list[self._read_cursor % self._buffer_size]
        self._read_cursor = self._read_cursor + 1
        return result

    def size(self):
        return self._write_cursor - self._read_cursor

if __name__ == "__main__":
    import threading, time

    ringbuffer = RingBuffer(5)
    MAX = 100
    def producer():
        count = 1
        while True:
            time.sleep(0.03)

            try:
                ringbuffer.append(count)
                if count == MAX:
                    break
                count = count + 1
            except RuntimeError, ex:
                pass

    def consumer():
        while True:
            time.sleep(0.01)
            try:
                element = ringbuffer.pop()
                print "pop: %d" % element
                if element == MAX:
                    break
            except RuntimeError as ex:
                pass
    
    prod = threading.Thread(target=producer)
    cons = threading.Thread(target=consumer)
    prod.start()
    cons.start()
    prod.join()
    cons.join()