协程通信之认识channel、阻塞

channel类型

这是go里面的核心数据类型,有了它我们可以方便的进行协程间数据通信。其原理来源于csp模型理论,go实现了部分理论。
简单说,csp模型由并发执行的实体(如进程或线程)组成,实体之间通过发消息进行通信,其中channel承担了实体和实体之间发送消息的通道。

在go里面goroutine就是实体,它里面也有个channel来完成通信。

// 定义一个函数
func sum(num int, c chan int) {
	res := num + 99

	// 数据写入通道
	c <- res
}

func main()  {
	// 定义通道
	c := make(chan int)

	go sum(100,c)

	ret := <-c

	fmt.Println(ret) // 打印:199
}

这就是一个最简单的主线程main和协程sum之间的通信。

阻塞

上面的代码中
对于发送者:如果没有接收者读取channel,则发送者会一直阻塞。
同样对于接收者:接收操作是阻塞的知道发送者发送数据。

根据上面的特性,就能实现当goroutine执行完成后得到数据。

func main()  {
	// 定义通道
	c := make(chan int)

	sum(100,c) // 去掉了go 就没有开启协程

	// 就执行不到这里了,程序被阻塞于此
	ret := <-c

	fmt.Println(ret) // 打印:199
}

这就是一个会阻塞的代码。

带缓冲的channel

c := make(chan int,2)

这就好比创建了一个带有容量=2的channel(好比队列),只有当队列塞满时发送者会阻塞,队列清空时接受着会阻塞。

// 定义一个函数
func sum(num int, c chan int) {
	res := num + 99

	// 数据写入通道
	c <- res
}

func main()  {
	// 定义通道
	c := make(chan int,2)

	sum(100,c)
	c <- 123
	c <- 456

	// 通道定义的容量2,但塞进了3条数据,被阻塞了
	// 执行不到下面
	fmt.Println("end") 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值