环形缓冲区模拟模型
#!/usr/bin/env python #encoding: utf8 # # import threading from time import ctime import time class MyThread(threading.Thread): def __init__(self, func, args, name=''): threading.Thread.__init__(self) self.name = name self.func = func self.args = args def run(self): print 'create %s'%self.name self.res = self.func(*self.args) class CQueue(): def __init__(self, len): self.cque = [] #circle queue self.ppos = 0 #put position self.gpos = 0 #get position self.clen = 0 #current position self.tlen = len #total length #init circle queue for i in range(len): self.cque.append(0) def get_item(self, n): return self.cque[n] def set_item(self, n, v): self.cque[n] = v def is_empty(self): return (self.clen == 0) def is_full(self): return (self.clen == self.tlen) def printst(self): print 'totalen=%d, clen=%d, ppos=%d, gpos=%d' % \ (self.tlen, self.clen, self.ppos, self.gpos) print str(self.cque) class Worker(): def __init__(self, qlen): self.cq = CQueue(qlen) self.qlock = threading.Lock() self.cv = threading.Condition(self.qlock) def writer(self): ''' writer: who writing item to queue. ''' while True: self.cv.acquire() print 'writer locked' self.cq.set_item(self.cq.ppos, 1) self.cq.ppos += 1 if self.cq.ppos == self.cq.tlen: #q is full, roll self.cq.ppos = 0 self.cq.clen += 1 self.cv.notify() self.cq.printst() self.cv.release() time.sleep(1) def reader(self): ''' reader who get item from queue. ''' while True: self.cv.acquire() print 'read locked' while self.cq.is_empty(): self.cv.wait() #read one print 'read one : %d' % self.cq.get_item(self.cq.gpos) self.cq.set_item(self.cq.gpos, 0) self.cq.gpos += 1 if self.cq.gpos == self.cq.tlen: #roll self.cq.gpos = 0 self.cq.clen -= 1 #self.cq.printst() self.cv.release() time.sleep(1) def do_work(): ''' do my job ''' w = Worker(10) w.cq.printst() threads = [] #create writer for i in range(1): t = MyThread(w.writer, (), 'writer') threads.append(t) #create reader for i in range(2): t = MyThread(w.reader, (), 'reader') threads.append(t) nth = len(threads) for i in range(nth): threads[i].start() for i in range(nth): threads[i].join() #main if __name__ == '__main__': do_work()