Golang之消息机制channel
程序员文章站
2022-05-19 14:15:19
...
1. 背景:
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已经退出。
解决主函数退出太快最直接的方法是让主函数睡眠一段时间:
这次输出结果确实是两趟。
可是等待的办法并不好,因为并不知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执行完毕之前,主线程一直阻塞。
推荐阅读
-
Android Studio 之 Android消息机制 之简单Demo --- 使用Handler和Message类来完成消息传递
-
Android消息机制三剑客之Handler、Looper、Message源码分析(一)
-
Android消息机制原理,仿写Handler Looper源码解析跨线程通信原理--之仿写模拟Handler(四)
-
Android 消息机制之深入学习MessageQueue
-
Qt之消息事件机制
-
Android开发之消息处理机制(一)——Handler
-
Android消息机制之ThreadLocal浅析
-
Android消息机制之线程间存储ThreadLocal源码分析
-
Android消息机制之ThreadLocal的工作原理
-
Android的消息机制之ThreadLocal的工作原理