go版生产者消费者模型
package main
import (
"fmt"
"time"
)
// 生产者
func Producer(inChannel chan<- int) {
defer close(inChannel)
for i := 1; i < 100; i++ {
inChannel <- i
}
time.Sleep(time.Second)
}
// 消费者
func ConSumer(outChannel <-chan int) {
for i := range outChannel {
fmt.Println(i)
}
time.Sleep(time.Second)
}
func main() {
mainInChannel := make(chan int, 3)
// 先启动消费者
go ConSumer(mainInChannel)
go Producer(mainInChannel)
time.Sleep(2 * time.Second)
}
sync.WaitGroup版:
// 带waitgroup的生产者
func ProducerWithWaitGroup(inChannel chan<- int) {
defer close(inChannel)
for i := 1; i < 10; i++ {
inChannel <- i
}
}
// 带waitgroup的消费者
func ConSumerWithWaitGroup(id int, outChannel <-chan int, wg *sync.WaitGroup) {
for {
// 当通道没值了,ok就为空,进入else
if i, ok := <-outChannel; ok {
fmt.Printf("task: %d - %d\n", id, i)
} else {
break
}
}
wg.Done()
}
func main() {
groupInChannel := make(chan int, 10)
var wg sync.WaitGroup
go ProducerWithWaitGroup(groupInChannel)
count := 3
wg.Add(count)
for i := 0; i < 3; i++ {
go ConSumerWithWaitGroup(i, groupInChannel, &wg)
}
wg.Wait()
}
Mutex锁版:
package main
import (
"fmt"
"sync"
)
var x int64
var wg sync.WaitGroup
var lock sync.Mutex
func Producer(taskId int) {
fmt.Printf("Producer-task: %d\n", taskId)
for i := 0; i < 5000; i++ {
lock.Lock() // 加锁
x = x + 1
lock.Unlock() // 解锁
}
fmt.Printf("Producer - task %d :now x = %d\n", taskId, x)
wg.Done()
}
func Consumer(taskId int) {
fmt.Printf("Consumer-task: %d\n", taskId)
for i := 0; i < 2000; i++ {
lock.Lock() // 加锁
x = x - 1
lock.Unlock() // 解锁
}
fmt.Printf("Consumer - task %d :now x = %d\n", taskId, x)
wg.Done()
}
func main() {
wg.Add(7)
for i := 0; i < 2; i++ {
go Producer(i)
}
for i := 0; i < 5; i++ {
go Consumer(i)
}
wg.Wait()
fmt.Printf("Final Result: %d\n", x)
}
// Consumer-task: 4
// Consumer - task 4 :now x = -2000
// Consumer-task: 2
// Consumer-task: 3
// Producer-task: 0
// Producer-task: 1
// Consumer-task: 1
// Consumer-task: 0
// Consumer - task 2 :now x = -4000
// Consumer - task 3 :now x = -6000
// Producer - task 0 :now x = -1000
// Producer - task 1 :now x = 4000
// Consumer - task 1 :now x = 2000
// Consumer - task 0 :now x = 0
// Final Result: 0