课程名称:GO开发工程师
课程章节:6-1:channel
课程讲师: ccmouse
课程内容:
创建channel:
func chanDemoDeadlock() {
//var c chan int 声明一个channel
c := make(chan int) // 创建一个channel
c <- 1 // 往channel里写数据
c <- 2
n := <-c // 从channel里读数据
fmt.Println(n) // fatal error: all goroutines are asleep - deadlock!
// deadlock的原因:往channel里写数据时没人接收
}
通过协程接收channel里的数据
func chanDemoGoRoutine() {
//var c chan int 声明一个channel
c := make(chan int) // 创建一个channel
go func() { // 创建协程去接收channel里数据
for { // 持续接收
n := <-c
fmt.Println(n)
}
}()
c <- 1 // 往channel里写数据
c <- 2
// 运行结果有可能只打印了1
// 原因:往channel里发2后主程序就结束了,协程还来不及打印
}
打印顺序:
func worker(i int, c chan int) {
for {
// printf 是io操作,输出的顺序不确定(会被调度器调度)
fmt.Printf("i: %d---> n: %c\n", i, <-c)
}
//i: 4---> n: e
//i: 5---> n: f
//i: 8---> n: i
//i: 6---> n: g
//i: 7---> n: h
//i: 1---> n: b
//i: 9---> n: j
//i: 0---> n: a
//i: 2---> n: c
}
func chanDemoWorker() {
var channels [10]chan int
for i := 0; i < len(channels); i++ {
go worker(i, channels[i]) // 将匿名函数提取为子函数
}
for i := 0; i < 10; i++ {
channels[i] <- 'a' + i
}
for i := 0; i < 10; i++ {
channels[i] <- 'A' + i
}
time.Sleep(time.Minute) // 延迟主程序main退出
}
提取工作子函数:
func createWorker(i int) chan int {
c := make(chan int)
go func() {
for {
fmt.Printf("i: %d---> n: %c\n", i, <-c)
}
}()
return c
}
func chanDemoCreateWorker() {
var channels [10]chan int
for i := 0; i < len(channels); i++ {
channels[i] = createWorker(i) // 将匿名函数提取为子函数
}
for i := 0; i < 10; i++ {
channels[i] <- 'a' + i
}
for i := 0; i < 10; i++ {
channels[i] <- 'A' + i
}
time.Sleep(time.Minute) // 延迟主程序main退出
}
课程收获:
- 注意channel 类型的写法 chan int