Golang之channel篇

99 阅读1分钟

无缓冲channel

channel使用注意点

  1. channel在<-ch没获取到值后,会阻塞掉,直到从ch中拿到值
  2. 循环从channel取值时不明确一共可以接收多少次就需要 协程close(ch)告诉什么时候channel传值结束
  3. 循环从channel取值时明确一共可以接收多少次,协程中就不用close(ch)
  4. 无缓冲channel传值前必须有接受值的,否则向channel传入就会造成死锁
package main

import (
	"fmt"
	"time"
)




/*
func main() {
	// 把上面代码main()函数初始化的单向 channel 修改为可读可写的 channel
	ch := make(chan int)
	go testData(ch)

	// 不明确就需要 协程告诉什么时候channel传值结束
	// for value := range ch {
	// 	fmt.Println(value)
	// }

	// 明确<-ch可以读取到多少个值,协程中就不用close(ch)
	for i := 0; i < 10; i++ {
		fmt.Println(<-ch)
	}
}

func testData(ch chan<- int) {
	for i := 0; i < 10; i++ {
		time.Sleep(time.Second)
		ch <- i
	}
	// close(ch)
}


*/

func main() {
	// channel在<-ch没获取到值后,会阻塞掉,直到从ch中拿到值
	ch := make(chan int)

	go unbufferChan(ch)
	for i := 0; i < 10; i++ {
		fmt.Println("receive  ", <-ch)
	}
}

func unbufferChan(ch chan int) {
	for i := 0; i < 10; i++ {
		fmt.Println("send ", i)
		time.Sleep(time.Second)
		ch <- i
	}
}

有缓冲channel

channel使用注意点

// 示例一
	// 创建缓冲大小为2的int类型channel
	ch := make(chan int, 2)

	// 发送数据到channel
	ch <- 1
	ch <- 2

	// 从channel中读取数据并打印
	fmt.Println(<-ch)
	fmt.Println(<-ch)
        
// 示例二
	ch := make(chan int, 2)
	ch <- 0
	ch <- 1
	close(ch)

	for i := 0; i < cap(ch)+1; i++ {
		v, ok := <-ch
		fmt.Println(v, ok)
	}
        
  channel := make(chan struct{})
	go func() {
		channel <- struct{}{}
	}()

	fmt.Println(<-channel)