前端开发者的Go语言之路(9) —— Channel 与 GoLang 的 CPS 模型

1. channel

goroutine 之间通信的通道就叫做 channel

image.png

1.1 创建使用 channel

定义一个 channel 类型:

var c chan int // c == nil

创建一个 channel:

c := make(chan int)

向一个 channel 发送数据:

c <- 1 // 将1发送给 channel 实例

接收一个 channel 发送的数据:

n := <-c

综合示例如下:

func chanDemo() {
   
	c := make(chan int)
	go func() {
   
		for {
   
			n := <-c
			fmt.Println(n)
		}
	}()
	c <- 1 // 如果发送一个channel却无人接收,那么就会产生死锁
	c <- 2
	time.Sleep(time.Millisecond)
}

func main() {
   
	chanDemo()
}

我们可以单独将 goroutine 抽离出来从而创建多个 goroutine,并建立多个 channel:

func worker(id int, c chan int) {
   
	for {
   
		fmt.Printf("Worker %d received %d\n", id, <-c)
	}
}

func chanDemo() {
   
	var channels [10]chan int
	for i := 0; i < 10; i++ {
   
		channels[i] = make(chan int)
		go worker(i, channels[i])
	}
	for i := 0; i < 10; i++ {
   
		channels[i] <- i
	}
	time.Sleep(time.Millisecond)
}

func main() {
   
	chanDemo()
}

同时创建 goroutine 与生成一个 channel 的步骤可以合并为一个步骤,返回的对象为一个 channel:

func createWorker(id int) chan int {
   
	c := make(chan int)
	go func() {
   
		for {
   
			fmt.Printf("Worker %d received %d\n", id, <-c)
		}
	}()
	return c
}

定义channel类型时,我们可以规定其只能接受数据或者只能发送数据:

channel := make(chan<- int) // channel 只能接收数据
channel := make(<-chan int) // channel 只能发送

这样的操作通常用于返回一个仅可以接收数据的channel。

1.2 使用 BufferChanel

使用了 buffer channel 后,会创建一个缓冲区,不必等待 channel 的接收者,因此可以接受数条数据并不让系统发生死锁,如下的的程序是合法的:

func bufferedChannel() {
   
	c := make(chan int, 3)
	c <- 1
	c <- 2
	c <- 3
    // c <- 4 超出缓冲区的部分却无接收对象的数据会让系统产生死锁
}

创建缓冲区可以优化性能,但是与平常的使用无异。

1.3 使用 close() 函数关闭 channel

使用 close(c chan<- Type) 方法可以用来关闭一个channel:

func channelClose() {
   
	c := 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值