golang-concurrency-tricks

看了一些 goroutine 的 patterns,(今天)觉得 goroutine 用起来是一种很爽的感觉

Channel over channel

Q:chan chan string 这样的数据类型的作用?

ref-1 的视频中使用到这一类型,用于 request & get response.

示例代码见 gist,能想到的应用: request 停止信号,response 错误信息。

Nil channel

这一 trick 在 ref-1 中也讲到了,但不清楚有什么比较实用的做法,看起来还是有更好的替代方法。

示例代码见 slide code

Channel as shuttle

有时想让某个 channel 满员后全部发送。

数量比较少的情况下

1
2
3
4
c := make(chan int, 2)
go routine(c, ...)
go routine(c, ...)
result := []int{<-c, <-c}

这种简单的方法在数量稍大些的情况下就变得非常的不优雅了,使用:

1
2
3
4
5
6
7
8
9
10
11
count := 5
wg := &sync.WaitGroup{}
c := make(chan int, count)
wg.Add(count)
for i := 0; i < count; i++ {
go func() {
defer wg.Done()
c <- i
}()
}
wg.Wait()

Channel 负载

在工程中遇到一段代码比较有意思

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
var (
queue = make(chan int, 3)
wg = &sync.WaitGroup{}
)

func consumer() {
for {
task, open := <-queue
if !open {
break
}
wg.Add(1)
go func(val int) {
defer wg.Done()
// some logic
}(task)
}
}

func producer() {
var arr []int
for i := 0; i < 1000000; i++ {
arr = append(arr, i)
}
for _, val := range arr {
select {
case queue <- val:
case <-time.After(time.Millesecond):
fmt.Print("producer timeout")
}
}
}

func main() {
go consumer()
producer()
wg.Wait()
}

之后继续学习并更新

References

0%