Introduction

Go 中的 Channel 除了通信功能,往往还会扮演信号量或阻塞控制的角色。后者往往只需要 Channel 的语言特性,并不关注 Channel 传输的内容。在此背景下就有了 struct{} 类型 Channel 的使用场景,该类型 Channel 不占用任何内存。该 Channel 只可以写入 struct{}{} ,即空结构体。

应用

1. 等待任务结束

1
2
3
4
5
6
7
8
done := make(chan struct{})
go func() {
doLongRunningThing()
close(done)
}()
// do some other things
// wait for that long running thing to finish
<-done

2. 多任务同时开始

实现类似并行而非并发的效果

1
2
3
4
5
6
7
8
9
10
start := make(chan struct{})
for i := 0; i < 10000; i++ {
go func() {
<-start // wait for the start channel to be closed
doWork(i) // do something
}()
}
// at this point, all goroutines are ready to go
// we just need to tell them to start by closing the start channel
close(start)

3. 事件中断

1
2
3
4
5
6
7
8
for {
select {
case m := <-email:
sendEmail(m)
case <-stop: // triggered when the stop channel is closed
break // (or return) exit
}
}