ringbuffer是一个无锁的环行缓冲区,它适用于一个线程读和一个线程写的场景。
ringbuffer会维护两个指针:
读写指针是一直向前前进的,然后通过 取模 的方式,将读写指针映射到缓冲区上。并且读指针一定不大于写指针。
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()