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

前端之家收集整理的这篇文章主要介绍了golang并发编程实践 -- 简单生产者消费者(with lock)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

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

  1. package main
  2. import (
  3. "fmt"
  4. "sync"
  5. "time"
  6. )
  7. type Queue struct {
  8. Elem []int
  9. Capacity int
  10. Front int
  11. Rear int
  12. Lock sync.Locker
  13. Cond *sync.Cond
  14. }
  15. func New() *Queue {
  16. theQueue := &Queue{}
  17. theQueue.Capacity = 10
  18. theQueue.Elem = make([]int,10)
  19. theQueue.Front,theQueue.Rear = 0,0
  20. theQueue.Lock = &sync.Mutex{}
  21. theQueue.Cond = sync.NewCond(theQueue.Lock)
  22. return theQueue
  23. }
  24. func (self *Queue) Put(e int) {
  25. self.Cond.L.Lock()
  26. // the Queue is full,Producer waits here
  27. // note that we use for not if to test the condition
  28. for self.Full() {
  29. self.Cond.Wait()
  30. }
  31. self.Elem[self.Rear] = e
  32. self.Rear = (self.Rear + 1) % self.Capacity
  33. self.Cond.Signal()
  34. defer self.Cond.L.Unlock()
  35. }
  36. func (self *Queue) Get() int {
  37. self.Cond.L.Lock()
  38. // the Queue is empty,Consumer waits here
  39. // note that we use for not if to test the condition
  40. for self.Empty() {
  41. self.Cond.Wait()
  42. }
  43. p := self.Elem[self.Front]
  44. self.Front = (self.Front + 1) % self.Capacity
  45. self.Cond.Signal()
  46. defer self.Cond.L.Unlock()
  47. return p
  48. }
  49. func (self *Queue) Empty() bool {
  50. if self.Front == self.Rear {
  51. return true
  52. }
  53. return false
  54. }
  55. func (self *Queue) Full() bool {
  56. if ((self.Rear + 1) % self.Capacity) == self.Front {
  57. return true
  58. }
  59. return false
  60. }
  61. func main() {
  62. theQueue := New()
  63. // producer puts
  64. go func() {
  65. for i := 1; i <= 100; i++ {
  66. time.Sleep(100 * time.Millisecond)
  67. theQueue.Put(i)
  68. fmt.Println("Bob puts ",i)
  69. }
  70. }()
  71. // consumer gets
  72. for i := 1; i <= 100; i++ {
  73. time.Sleep(100 * time.Millisecond)
  74. p := theQueue.Get()
  75. fmt.Println("Alice gets : ",p)
  76. }
  77. }

运行效果如下:
  1. Bob puts 1
  2. Alice gets : 1
  3. Bob puts 2
  4. Alice gets : 2
  5. Bob puts 3
  6. Alice gets : 3
  7. Bob puts 4
  8. Alice gets : 4
  9. Bob puts 5
  10. Alice gets : 5
  11. Bob puts 6
  12. Alice gets : 6
  13. Bob puts 7
  14. Alice gets : 7
  15. Bob puts 8
  16. Alice gets : 8
  17. Bob puts 9
  18. Alice gets : 9
  19. Bob puts 10
  20. Alice gets : 10
  21. Bob puts 11
  22. Alice gets : 11
  23. Bob puts 12
  24. Alice gets : 12
  25. Bob puts 13
  26. Alice gets : 13

.......

如此反复直到100次。

猜你在找的Go相关文章