并发 concurrency
-从源码解析来看, goroutine
只是由官方实现的超级 “线程池” 而已
-并发部署并行
-并发主要由切换时间片段来实现 “同时” 运行,并行则是直接利用多核实现多线程的运行,但 Go 可以设置使用核数,以发挥多核计算机的能力
import (
"fmt"
"time"
)
func main() {
go Go()
//等待两秒
time.Sleep(2 * time.Second)
}
func Go() {
fmt.Println("Go Go Go!!!")
}
goroutine
奉行通过通信来共享内存,而不是共享内存来通信
channel
-channel
是 goroutine
沟通的桥梁,大都是阻塞同步的
-通过 make
创建, close
关闭
-channel
时引用类型
-可以使用 for range
来迭代不断操作 channel
-可以设置单向或双向通道
-可以设置缓存大小,在未被填满前不会发生阻塞
func main() {
c := make(chan bool)
go func() {
fmt.Println("Go Go Go!!!")
c <- true
close(c)
}()
for v := range c {
fmt.Println(v)
}
}
select
-可处理一个或多个 channel
的发送和接收
-同时有多个可用的 channel
是按随机顺序处理
-可用空的 select
来阻塞 main
函数
-可设置超时
func main() {
c1, c2 := make(chan int), make(chan string)
o := make(chan bool)
go func() {
for {
select {
case v, ok := <-c1:
if !ok {
o <- true
break
}
fmt.Println("c1:",v)
case v, ok := <-c2:
if !ok {
o <- true
break
}
fmt.Println("c2:",v)
}
}
}()
c1 <- 1
c2 <- "hi"
c1 <- 3
c2 <- "hello"
close(c1)
<-o
}
select
发送
func main() {
c := make(chan int)
go func() {
for v := range c {
fmt.Println(v)
}
}()
for {
select {
case c <- 0:
case c <- 1:
}
}
}
select
设置超时
import (
"fmt"
"time"
)
func main() {
c := make(chan bool)
select {
case v:= <-c:
fmt.Println(v)
case <-time.After(3 * time.Second):
fmt.Println("Timeout")
}
}
课后习题
var c chan string
func Pingpang() {
i := 0
for {
fmt.Println(<-c)
c <- fmt.Sprintf("From Pingpang: Hi, #%d", i)
i++
}
}
func main() {
c = make(chan string)
go Pingpang()
for i := 0; i < 10; i++ {
c <- fmt.Sprintf("From Pingpang: Hello, #%d", i)
fmt.Println(<-c)
}
}
当前内容版权归 Programming-With-Love 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 Programming-With-Love .