简介

Golang 最亮的就是 goruntime 和 channel 的组合可以很容做好高并发,下面是一个简单的生产者和消费者模型适合入门学习。

channel 使用有特别多需要注意的地方下面是一些注意点。

Channel Tricks

暴力关闭 channel

package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	jobs := make(chan int)
	var wg sync.WaitGroup

	//	定时直接关闭channel
	go func() {
		time.Sleep(time.Second * 3)
		close(jobs)
	}()

	//	无脑向channel发送数据【向已经关闭的channel发送数据会直接panic】
	go func() {
		for i := 0; ; i++ {
			jobs <- i
			fmt.Println("produce:", i)
		}
	}()
	//	在channel中读取数据
	wg.Add(1)
	go func() {
		defer wg.Done()
		for i := range jobs {
			fmt.Println("consume:", i)
		}
	}()
	wg.Wait()
}

优雅关闭 channel

package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	jobs := make(chan int)
	timeout := make(chan bool)
	var wg sync.WaitGroup

	//	总时间限制
	go func() {
		time.Sleep(time.Second * 3)
		timeout <- true
	}()
	//	生产
	go func() {
		for i := 0; ; i++ {
			select {
			//	时间用完停止channel
			case <-timeout:
				close(jobs)
				close(timeout)
				return
			//	正常生产
			default:
				jobs <- i
				fmt.Println("produce:", i)
			}
		}
	}()
	//	消费者
	wg.Add(1)
	go func() {
		defer wg.Done()
		for i := range jobs {
			fmt.Println("consume:", i)
		}
	}()
	wg.Wait()
}