golang select default continue_golang系列——goroutine

40fc0572a17812821be6784279c9764c.png

golang的最大特点之一就是天然支持基于goroutine的高并发操作。本文将介绍goroutine的相关知识。

并发:相同的处理器顺序处理多个任务,可以理解为左手拿面包,右手拿啤酒,由于只有一张嘴,所以嘴是并发的吃。 并行:不同的处理器同事处理多个任务,可以理解为左手画圆,右手画方,左右手是并行的行动。

进程:操作系统管理,可以近似认为是程序所有代码的一次动态执行;线程:操作系统管理,可以近似认为是程序部分代码的一次动态执行; 协程:程序自行管理,可以近似认为是程序任意函数的一次动态执行; goroutine:系统和程序共同管理,系统管理资源调度等,程序管理应用逻辑;是golang自行封装过的协程,可以近似认为是协程,以下均称协程。

如下所示,在golang中起一个协程非常简单

func 

每次通过Sleep等待协程执行结束是不现实的,因为实际中我们无法判断协程何时结束,所以引入WaitGroup来监控协程的执行状态。WaitGroup内部维护一个计数器,通过Add()、Done()和Wait()对计数器进行加1、减1和阻塞等待操作,当计数器为0时,所有协程执行完毕,则主程序结束。

import 

那协程之间如何竞争资源和通信呢?传统方法是通过共享锁或互斥锁竞争资源,而在golang中建议使用channal,同时golang团队建议:不要通过共享内存来通信,而是通过通信来共享内存。这怎么理解呢?不要试图通过控制内存的使用权限来进一步获取内存数据,而是各个协程利用通信机制直接获取内存数据达到共享的目的。通常我们利用加锁来获取某个变量、代码或内存的使用权,从而获得数据;而在golang中,我们直接通过channal通信获取数据。

channal(通道)

通道按功能可以分成只读、只写和可读可写三种,按容量可以分为有缓冲和缓冲两种。

//模板,声明双向通道

channal的读写权限主要看“箭头”的方向,“箭头”方向就是数据流动的方向。

ch 

很多同学有疑问,不能写入,那只读通道从哪儿读呢,或者不能读取,只写通道的数据又有什么意义呢?其实在使用时,只读和只写通道都是基于可读可写通道的,只是赋予的功能不同。例如上面的代码,对chWrite的写入实际是对ch的写入,对chRead读取实际是对ch的读取。也就是对ch的读写操作都通过chWrite和chRead完成。

多协程协同工作时,利用公共的channal通信共享数据。

var 

channel 和 select

select是golang的一个关键字,常常与channal一起使用,主要的作用类似switch等选择语句,但在使用时有几点特性:
1、case后的表达式必须是通信
2、所有channal表达式都会被求值。
3、当一个或多个case满足条件时,会随机选一个执行。
4、如果有default,则当无case满足条件时执行;若没有defualt语句,则select将阻塞,直到某个case满足条件。

ch1 

如上代码所示:
1、三个case都是通信
2、三个case都是channal表达式(2次写入和1次读取),都会被求值;
3、三个case都满足,则随机挑选一个执行,故多次执行后输出可能不同。

ch4 

4、如上所示,有default语句且其他case语句不满足,则执行default语句输出“case default”;如果没有default语句,那么1秒之后,第二个case语句满足,则会输出“case timeout”,这也是select常见的用法之一:判断超时。

channal的循环

ch

for循环是golang语言中的唯一循环结构,同时在channal写完毕后需要close,类似文件读取完成后需要关闭,否则之后若发生读取操作,则会发生panic;同时close过的通道不能被再次close。

另外大家可以发现元素v的地址输出都相同,所以如果需要穿参数,那一定要传值喔,不能传地址。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值