go routine初解 | 青训营笔记

43 阅读2分钟

这是我参与[第五届青训营]的第十二天

goroutine是一个轻量级的执行线程。

可以为匿名函数调用启动一个 go routine。

package main

import (
    "fmt"
    "time"
)

func f(from string) {
    for i := 0; i < 3; i++ {
        fmt.Println(from, ":", i)
    }
}

func main() {

    f("direct")

    go f("goroutine")

    go func(msg string) {
        fmt.Println(msg)
    }("going")

    time.Sleep(time.Second)
    fmt.Println("done")
}

如果我们的两个函数调用在单独的go routine中异步运行。等待完成(更可靠的方法,使用WaitGroup)。

$ go run goroutines.go
 direct: 0
 direct: 1
 direct: 2
 goroutine: 0
 going
 goroutine: 1
 goroutine: 2
 done
  • 频道(Channels)
package main

import "fmt"

func main() {

    messages := make(chan string)

    go func() { messages <- "ping" }()

    msg := <-messages
    fmt.Println(msg)
}

通道(channel)是go语言中用于连接并发go routine的通道。

默认情况下发送和接收块,直到发送方和接收方都准备好。此属性允许我们在程序结束时等待"ping" 消息,而无需使用任何其他同步。

  • 通道缓冲(Channel BUffering)
package main

import "fmt"

func main() {

    messages := make(chan string, 2)

    messages <- "buffered"
    messages <- "channel"

    fmt.Println(<-messages)
    fmt.Println(<-messages)
}

默认情况下,通道是无缓冲的,这意味着chan <-如果有相应的 receive( <- chan) 准备好接收发送的值,它们将只接受 sends()。缓冲通道接受有限数量的值,而这些值没有相应的接收器。

这里make有一个字符串通道,最多缓冲2个值

因为通道是缓冲的,可以将这些值发送到通道中而无需相应的并发接收。

  • 通道同步(Channel Synchronization)
package main

import (
    "fmt"
    "time"
)

func worker(done chan bool) {
    fmt.Print("working...")
    time.Sleep(time.Second)
    fmt.Println("done")

    done <- true
}

func main() {

    done := make(chan bool, 1)
    go worker(done)

    <-done
}

上面使用的done通道将用于通知另一个go routine。

发送一个值以告知已完成

启动一个 worker goroutine,为其提供通知通道。

  • 通道方向(Channel Directions)
package main

import "fmt"

func ping(pings chan<- string, msg string) {
    pings <- msg
}

func pong(pings <-chan string, pongs chan<- string) {
    msg := <-pings
    pongs <- msg
}

func main() {
    pings := make(chan string, 1)
    pongs := make(chan string, 1)
    ping(pings, "passed message")
    pong(pings, pongs)
    fmt.Println(<-pongs)
}

使用通道作为函数参数时,可以指定通道是仅用于发送还是接收值。这种特殊性增加了程序的类型安全性。