Golang之消息机制channel

1. 背景:

1. 对于以下这段代码:
Golang之消息机制channel_第1张图片
按照想法应该输出 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
但是,输出结果是: 0 1 2 3 4 5 6 7 8 9
2. 原因:
在goroutine还未来得及跑loop函数时,主函数main已经退出。
解决主函数退出太快最直接的方法是让主函数睡眠一段时间:
Golang之消息机制channel_第2张图片
这次输出结果确实是两趟。
可是等待的办法并不好,因为并不知goroutine要执行多长时间,只能尽可能长的设置主函数的sleep,这样会让主函数执行时间远大于实际执行时间。
3. 需要找一个方法,让goroutine快执行完时通知主函数,即阻塞住主routine,类似Java中的A.join()函数(调用方必须等待A执行完毕返回后再返回),那么涉及多个goroutine间通信,go中的channel就起了这样的作用。

2. channel

1.定义:
channel是Golang语言在语言层级提供的goroutine间的通信方式,可以使用channel在多个goroutine之间传递消息。
2.使用:
channel是类型相关的,一个channel只能传递一种类型的值,传递类型需要在声明channel时指定。
3.声明:
1. var chanName chan ElementType
举例:声明一个传递int类型的channel:var ch chan int

2. 使用内置函数make()定义一个带缓冲的channel
ch := make(chan int, 1024)

ch := make(chan int, 1024 )
3. 单向channel的声明:
var ch2 chan <- int    // 只用于写int数据
var ch3 <-chan int    // 只用于读int数据
4. 通过类型转换将一个普通channel转换为单向:
ch4 := make(chan int)
ch5 := <-chan int(ch4)   // 单向读
ch6 := chan<- int(ch4)  //单向写
4.用法:
1. 写入:
ch <- value(将一个数据value写入channel,如果channel已满则导致阻塞,直至channel中有空闲)
2. 读取:
value := <-ch(从channel中读取数据,如果channel为空那么会导致阻塞,直至channel中有数据)

channel的发送和接收都是阻塞的。

3. 关闭不再使用的channel
close(ch)
应该在生产者的地方关闭channel,如果在消费者的地方关闭,容易引起panic;
而在一个已关闭的channel上执行读取操作总是能够立即返回,返回值是对应类型的零值。

5. 改进:
上面图中的例子可用一个信道来通知主线,当loop执行完毕,向信道中存入一个数据0,主线程开启一个goroutine后,需要从信道中读数据,那么当loop执行完毕之前,主线程一直阻塞。
Golang之消息机制channel_第3张图片

你可能感兴趣的:(Go开发)