golang goroutine

package main

import (
    "fmt"
    "time"
)

// 工作程序
func work(n int, i int, result chan interface{}, finish chan int) {
    fmt.Printf("共计%v个协程,现%v号正在执行\n", n, i)
    for j := 1; j <= 5; j++ {
        result <- j
        time.Sleep(time.Second)
    }
    finish <- 1
}

// 完成通知
func complete(n int, finish chan int, result chan interface{}) {
    i := 0
    for {
        _, ok := <-finish
        if !ok {
            break
        }
        i++
        if i == n {
            break
        }
    }
    close(finish)
    close(result)
}

// 处理数据
func handle(result chan interface{}, exit chan bool) {
    for {
        v, ok := <-result
        if !ok {
            break
        }
        fmt.Printf("读到数据=%v\n", v)
    }
    exit <- true
    close(exit)
}

// 主程序
func main() {
    // n个协程同时执行
    n := 100

    // 每个协程计算后的数据放到result通道中
    result := make(chan interface{}, n*5)
    // 每个协程计算完成后告知finish通道完成,继而关闭result通道
    finish := make(chan int, n)
    // result通道中的数据处理完毕后,通知exit通道可以退出主程序
    exit := make(chan bool, 1)

    for i := 1; i <= n; i++ {
        go work(n, i, result, finish)
    }
    go complete(n, finish, result)
    go handle(result, exit)

    <-exit

    fmt.Println("程序执行完毕,原则上需要100个5秒的时间执行,而现在只需要5s的时间就可以执行完毕")
}