模式
type receiver struct {
sync.WaitGroup
data chan int
}
func newReceiver() *receiver {
r := &receiver{
data: make(chan int),
}
r.Add(1)
go func() {
defer r.Done()
for x := range r.data {
println("recv:", x)
}
/*for {
x, ok := <-r.data //使用ok-idom读取chan 里的数据
if !ok {
println("data chan is closed...")
return
}
println("recv:", x)
}*/
}()
return r
}
func main() {
r := newReceiver()
r.data <- 1
r.data <- 2
close(r.data)
r.Wait()
}
- 通道本身就是一个并发安全的队列,可用作ID generator、Pool等用途
type pool chan []byte
func newPool(cap int) pool {
return make(chan []byte, cap)
}
func (p pool) get() []byte {
var v []byte
select {
case v = <-p:
default: //通道不可用时,创建空字节切片
v = make([]byte, 10)
}
return v
}
func (p pool) put(b []byte) {
select {
case p <- b:
default: //通道不可用时 做其它操纵
println("channel is full...")
}
}
func main() {
m := newPool(2)
sByte1 := []byte{1, 2, 3}
sByte2 := []byte{10, 20, 30}
sByte3 := []byte{100, 200, 222}
sByte4 := []byte{4, 5, 6}
m.put(sByte1)
m.put(sByte2)
m.put(sByte3)
m.put(sByte4)
fmt.Println(m.get())
fmt.Println(m.get())
fmt.Println(m.get())
fmt.Println(m.get())
fmt.Println(m.get())
/*
channel is full...
channel is full...
[1 2 3]
[10 20 30]
[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0]
*/
}
func main() {
runtime.GOMAXPROCS(4)
wg := sync.WaitGroup{}
sem := make(chan struct{}, 2) //最多允许2个并发同时执行
for i := 0; i < 5; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
sem <- struct{}{}
defer func() { <-sem }() //释放信号
time.Sleep(time.Second * 2)
fmt.Println(id, time.Now())
}(i)
}
wg.Wait()
}