课程名称:GO开发工程师
课程章节:6-2:使用channel等待goroutine结束;6-3:使用channel遍历树
课程讲师: ccmouse
课程内容:
- 使用channel等待goroutine结束示例:
type worker struct {
in chan int
done chan bool
}
func doWork(id int, c chan int, done chan bool) {
for n := range c {
fmt.Printf("id: %d---> n: %c\n", id, n)
done <- true
}
}
func createWorker(id int) worker {
w := worker{
in: make(chan int),
done: make(chan bool),
}
go doWork(id, w.in, w.done)
return w
}
func chanDemo() {
workers := make([]worker, 10)
for i := 0; i < 10; i++ {
workers[i] = createWorker(i)
}
for i, w := range workers {
w.in <- 'a' + i
}
for _, w := range workers {
<-w.done // 使用channel来等待 goroutine结束
}
}
- 使用内建对象 sync.WaitGroup 来控制goroutine结束示例:
type worker2 struct {
in chan int
done func() // 传一个函数,具体的关闭方法由使用者写在函数体内
}
func doWork2(id int, w worker2) {
for n := range w.in { //
fmt.Printf("id: %d---> n: %c\n", id, n)
w.done()
}
}
func createWorker2(id int, wg *sync.WaitGroup) worker2 {
w := worker2{
in: make(chan int),
done: func() {
wg.Done()
},
}
go doWork2(id, w)
return w
}
func chanDemo2() {
var wg sync.WaitGroup // 内建对象
workers := make([]worker2, 10)
for i := 0; i < 10; i++ {
workers[i] = createWorker2(i, &wg)
}
wg.Add(20) // 20个并发任务
for i, w := range workers {
w.in <- 'a' + i
}
for i, w := range workers {
w.in <- 'A' + i
}
wg.Wait() // 等待20个并发任务完成
}
- 使用channel遍历树示例:
// 内部实现者:
func (node *Node) TraverseWithChan() chan *Node {
out := make(chan *Node)
go func() {
node.TraverseFunc(func(node *Node) {
out <- node
})
close(out)
}()
return out
}
// 外部使用者:
c := root.TraverseWithChan()
maxNode := 0
for node := range c {
if node.Value > maxNode {
maxNode = node.Value
}
}
课程收获:
- channel 输入数据是阻塞式的。