并发编程
·Go语言是原生支持语言级并发的,这个并发的最小逻辑单元就是goroutine。goroutine就是Go语言提供的一种用户态线程。
·用户态线程是跑在内核级线程之上的,goroutine在运行时的调度是由Go语言提供的调度器来进行的,创建一个goroutine使用关键字go,go创建的goroutine不会阻塞主线程。
进程、线程、协程的概念
1.进程就是应用程序的启动实例。
例如:打开一个软件,就是开启了一个进程。
进程拥有代码和打开的文件资源,数据资源,独立的内存空间。
2.线程属于进程,是程序的执行者。
一个进程至少包含一个主线程,也可以有更多的子线程。
线程有两种调度策略,一是:分时调度,二是:抢占式调度。
3.协程是轻量级线程, 协程的创建、切换、挂起、销毁全部为内存操作,消耗是非常低的。
协程是属于线程,协程是在线程里执行的。
协程的调度是用户手动切换的,所以又叫用户空间线程。
协程的调度策略是:协作式调度。
并发编程-创建goroutine
使用关键词go,即可创建一个goroutine,当调用的函数返回时,goroutine自动结束。
输出结果:
im goroutine:2
im goroutine:1
im goroutine:0
im goroutine:0
im goroutine:1
im goroutine:2
…
Channel
·Channel是Go中的一个核心类型,可以把它看成一个管道,通过它可以发送或者接收数据进行通讯(communication)。配合goroutine,可以形成既简单又强大的请求处理模型。
·有以下四个特性:
1.goroutine安全
2.在不同的goroutine之间存储和传输值
3.提供FIFO语义(buffered channel提供)
4.让goroutine block/unblock
Channel-声明&初始化
1.无缓冲的channel,当放入1个元素后,后续发送便会阻塞。直到缓冲区为空后,发送成功返回
2.带缓冲的channel,当缓冲区满后,后续发送便会阻塞。直到缓冲区有空位,发送成功返回
3.接收数据时,当缓冲区未空,则阻塞。直到有数据或channel被关闭
Channel-示例
输出结果(不是一定的,测试几次看看):
send num:0
send num:1
recv num:0
recv num:2
recv num:1
end
Channel与Select
select 用法类似与 IO 多路复用,可以同时监听多个 channel 的消息状态。
·select 可以同时监听多个 channel 的写入或读取;
·执行 select 时,若只有一个 case 通过(不阻塞),则执行这个 case 块,若有多个 case 通过,则随机挑选一个 case 执行;
·若所有 case 均阻塞,且定义了 default 模块,则执行 default 模块。若未定义 default 模块,则 select 语句阻塞,直到有 case 被唤醒;
·使用 break 会跳出 select 块;