笔记 - goroutine、channel详解

Golang
358
0
0
2022-10-11
标签   Golang基础
  • goroutine
  • channel通道 (goroutine通信)
package main
import "fmt"
func main() {
var ch1 chan bool
ch1 = make(chan bool)
go func() {
for i := 0; i < 10; i++ {
fmt.Println("子goroutine:", i)
}
ch1 <- true
fmt.Println("over")
}()
// 读数据是阻塞的
<-ch1
fmt.Println("main over")
}
  • 关闭通道及范围循环
package main
import (
"fmt"
"time"
)
func main() {
ch1 := make(chan int)
go sendData(ch1)
// 第一种方式读取通道
for {
time.Sleep(1 * time.Second)
v, ok := <-ch1
if !ok {
fmt.Println("读完了 over")
break
}
fmt.Println("读取数据", v)
}
// 第二种方式读取通道
for v := range ch1 { // v <- ch1
fmt.Println("数据:", v)
}
fmt.Println("main.... over...")
}
func sendData(ch1 chan int) {
for i := 0; i < 10; i++ {
time.Sleep(1 * time.Second)
ch1 <- i
}
// 关闭通道
close(ch1)
}
  • 缓存通道(可理解为一个定长的队列)
package main
import (
"fmt"
"strconv"
)
func main() {
/**
* 非缓冲 make(chan T)
* 缓冲 make(chan T, capacity)
* 发送: 缓冲区的数据满了,才会阻塞
* 接受: 缓冲区的数据空了,才会阻塞
*/
ch1 := make(chan int)
fmt.Println(len(ch1), cap(ch1))
ch1 <- 100
ch2 := make(chan int, 5)
fmt.Println(len(ch2), cap(ch2))
ch2 <- 100
fmt.Println(len(ch2), cap(ch2))
ch3 := make(chan string, 4)
go sendData(ch3)
for {
v, ok := <-ch3
if !ok {
fmt.Println("读完了...", ok)
break
}
fmt.Println("读取的数据是:", v)
}
fmt.Println("main over")
}
func sendData(ch chan string) {
for i := 0; i < 10; i++ {
ch <- "data" + strconv.Itoa(i)
fmt.Printf("子gorountine第%d个数据", i)
}
close(ch)
}
  • 定向通道
package main
import "fmt"
func main() {
/**
双向通道:
chan T
chan <- data, 发送数据,写出
data <- chan, 获取数据,读取
单向通道: 定向
chan <- T, 只支持写
<-chan T, 只支持读
*/
ch1 := make(chan string)
ch2 := make(chan<- int) // 单项,只能写,不能读
ch3 := make(<-chan int) // 单项。只能读,不能写
go sendData(ch1)
data := <-ch1 // 读取
fmt.Println("子roroutine数据", data)
ch1 <- "我是main"
}
func sendData(ch1 chan string) {
ch1 <- "我是子"
data := <-ch1
fmt.Println("main goroutine传来:", data)
}