Learn Golang in Days - Day 16-Go并发
简介
- go语言支持并发,只需要使用go关键字开启goroutine即可。
- goroutine是轻量级现场,goroutine由运行时进行调度管理
package main
import "fmt"
import "time"
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("world")
say("hello")
}
通道channel
- 通道channel是用来传递数据的一个数据结构
- 通过可用于goroutine之间通过传递一个指定类型的值来同步运行通信。
- 操作符
<-
用于指定通道的方向,发送或接收。 - 如果没有指定方向,则为双向通道
ch <- v //v 发送到通道ch
v := <- ch //从通道ch接收数据,并赋值给v
- 声明通道
- 默认情况下,通道是不带缓冲区的。
ch := make(chan int)
- 例子
package main
import (
"fmt"
)
// 求和
func sum(s []int, c chan int) {
sum := 0
fmt.Printf("0***********\n")
fmt.Println(s)
for _, v := range s {
fmt.Printf("%d\t",v)
sum += v
}
c <- sum
fmt.Printf("\n1***********\n")
}
func main() {
// 初始化切片
s := []int{61,2123,123,55,66,7,7,8,88,9,990,4343,2342, 7, 3, 4, 5, 8}
// 创建通道
c := make(chan int)
//启动两个协程
go sum(s[:len(s)/2], c)
go sum(s[len(s)/2:], c)
// 从通道中接收
x, y := <-c, <-c
fmt.Println("\n---------------------")
fmt.Println(x, y, x+y)
}
遍历通道与关闭通道
- Go通过range关键字来遍历读取通道的数据,类似于数组与切片
v, ok := <- ch
package main
import "fmt"
import "time"
func main() {
c := make(chan int, 10)
go fibonacci(cap(c), c)
//遍历
for i := range c {
fmt.Println(i)
}
}
//斐波那契数列
func fibonacci(n int, c chan int) {
x, y := 0, 1
for i := 0; i < n; i++ {
fmt.Println(time.Now())
time.Sleep(3 * time.Second)
// x 发送给通道c
c <- x
x, y = y, x+y
}
close(c)
}
有疑问加站长微信联系(非本文作者)