Go程(goroutine)是由Go运行时管理的轻量级线程。
# 启动一个Go程并执行f(x, y, z)
go f(x, y, z)
note:f、x、y、z的求值在当前Go程中,而f的执行发生在新的Go程中。
Go程在相同的地址空间中运行,因此在访问共享内存时必须进行同步。
package main
import (
"fmt"
"time"
)
func fff(s string) {
for i := 0; i < 5; i++{
fmt.Println(s, i)
}
}
func main() {
go fff("aaa")
fff("iii")
}
信道是带有类型的管道,可以使用信道操作符<-来发送或接收值。
# 将v发送至信道ch
ch <- v
# 从ch接收值并赋予v
v := <-ch
note:“箭头就是数据流的方向”。
信道在使用前必须先创建。
# 创建信道
ch := make(chan int)
默认情况下,发送与接收操作在另一端准备好之前都会阻塞。这使得Go程在没有显式锁或条件变量的情况下进行同步。
package main
import "fmt"
func sum(s []int, c chan int) {
sum := 0
for _, v := range s {
sum += v
}
c <- sum
}
func main() {
s := []int{7, 2, 8, -9, 4, 0}
c := make(chan int)
go sum(s[:len(s)/2], c)
go sum(s[len(s)/2:], c)
x, y := <-c, <-c
fmt.Println(x, y, x + y)
}
信道可以带缓冲,将缓冲长度作为第二个参数提供给make来初始化一个带缓冲的信道
ch := make(chan int, 100)
仅当信道的缓冲区填满后,向其发送数据时才会阻塞。当缓冲区为空时,接收方会阻塞。
package main
import "fmt"
func main() {
c := make(chan int, 5)
len := 2
for i := 0; i < len; i++ {
c <- i
}
for i := 0; i < len; i++ {
fmt.Println(<-c)
}
}