Golang 协程并发

352 阅读1分钟

协程并发

Go 语言支持并发,只需要通过 go 关键字开启协程 goroutine 即可 goroutine 是轻量级线程,它的调度是由 Golang 程序运行时进行管理的 每一个 goroutine 执行一个函数,同一个程序中的所有 goroutine 共享同一个地址空间

goroutine 语法格式如下

go 函数名 ( 参数列表 )

go f (x, y, z)

sleep

// 睡眠1秒,等待上面两个协程结束

func say (s string) {
    for i := 0; i <= 5; i++ {
        fmt.Println(s)
    } 
}

func main () {
    go say("world")

    say("hello")

    var ss = "golang"
    go func (s string) {
        for i := 0; i <= 5; i++ {
            fmt.Println(s)
        } 
    }(ss)

    time.Sleep(time.Second * 1)
}

sync.WaitGroup

// 使用 sync.WaitGroup,等待上面两个协程结束

func say (s string, wg *sync.WaitGroup) {
    defer wg.Done()    // 操作完成,减少一个计数

    for i := 0; i <= 5; i++ {
        fmt.Println(s)
    } 
}

func main () {
    var wg sync.WaitGroup
    wg.Add(2)    // 因为有两个动作,所以增加2个计数

    go say("world", &wg)

    var ss = "golang"
    go func (s string) {
        defer wg.Done()   // 操作完成,减少一个计数

        for i := 0; i <= 5; i++ {
            fmt.Println(s)
        } 
    }(ss)

    wg.Wait()   // 等待,直到计数为0
}

channel

// 使用通道,等待上面两个协程结束

func main () {
    ch := make(chan struct{})
    count := 2    // count 表示活动的协程个数

    go func () {
        fmt.Println(123)
        ch <- struct{}{}  // 协程结束,发出信号
    }

    go func () {
        fmt.Println(456)
        ch <- struct{}{}   // 协程结束,发出信号
    }

    for range ch {
        // 每次从 ch 中接收数据,表示一个活动的协程结束 
        count--
        // 当所有活动的协程都结束时,关闭通道
        if count == 0 {
            close(ch)
        }
    }
}