golang并发编程实践 -- 简单生产者消费者(with lock)

来源:互联网 发布:诺基亚5235软件下载 编辑:程序博客网 时间:2024/06/10 07:25

上一篇文章用golang中的channel实现了简单的消费者模型,下面的版本是用传统的锁技术实现的版本,相对比会发现golang提供的channel更好用。而且golang的channel可以完成很多在别的语言里需要很多代码才能实现的功能。以后陆续解答。

package mainimport ("fmt""sync""time")type Queue struct {Elem     []intCapacity intFront    intRear     intLock     sync.LockerCond     *sync.Cond}func New() *Queue {theQueue := &Queue{}theQueue.Capacity = 10theQueue.Elem = make([]int, 10)theQueue.Front, theQueue.Rear = 0, 0theQueue.Lock = &sync.Mutex{}theQueue.Cond = sync.NewCond(theQueue.Lock)return theQueue}func (self *Queue) Put(e int) {self.Cond.L.Lock()// the Queue is full, Producer waits here// note that we use for not if to test the conditionfor self.Full() {self.Cond.Wait()}self.Elem[self.Rear] = eself.Rear = (self.Rear + 1) % self.Capacityself.Cond.Signal()defer self.Cond.L.Unlock()}func (self *Queue) Get() int {self.Cond.L.Lock()// the Queue is empty, Consumer waits here// note that we use for not if to test the conditionfor self.Empty() {self.Cond.Wait()}p := self.Elem[self.Front]self.Front = (self.Front + 1) % self.Capacityself.Cond.Signal()defer self.Cond.L.Unlock()return p}func (self *Queue) Empty() bool {if self.Front == self.Rear {return true}return false}func (self *Queue) Full() bool {if ((self.Rear + 1) % self.Capacity) == self.Front {return true}return false}func main() {theQueue := New()// producer putsgo func() {for i := 1; i <= 100; i++ {time.Sleep(100 * time.Millisecond)theQueue.Put(i)fmt.Println("Bob puts ", i)}}()// consumer getsfor i := 1; i <= 100; i++ {time.Sleep(100 * time.Millisecond)p := theQueue.Get()fmt.Println("Alice gets : ", p)}}

运行效果如下:

Bob puts  1Alice gets :  1Bob puts  2Alice gets :  2Bob puts  3Alice gets :  3Bob puts  4Alice gets :  4Bob puts  5Alice gets :  5Bob puts  6Alice gets :  6Bob puts  7Alice gets :  7Bob puts  8Alice gets :  8Bob puts  9Alice gets :  9Bob puts  10Alice gets :  10Bob puts  11Alice gets :  11Bob puts  12Alice gets :  12Bob puts  13Alice gets :  13

.......

如此反复直到100次。

原创粉丝点击