Go基础知识梳理(四)
Go基础知识梳理(四)
GO的哲学是“不要通过共享内存来通信,而是通过通信来共享内存”,通道是GO通过通信来共享内存的载体。
rumtime包常用方法
runtime.NumGoroutine() //返回当前程序的协程数量
runtime.GOMAXPROCS(0) //获取当前的GOMAXPROCS数量
runtime.GOMAXPROCS(2) //设置程序的GOMAXPROCS数量为2
goroutine
特性
- 执行是非阻塞的,不会等待
- go 后面的返回值会被忽略
- 调度器不能保证goroutine的执行顺序
fun main() {
//另起一个协程去打印
go func() {
fmt.Println("goruntine")
}()
}
chan
//创建chan
c := make(chan dataType)
//无缓冲, len 和 cap 都是0
fmt.Println(len(c)) //0
fmt.Println(cap(c)) //0
//有缓冲
c = make(chan dataType, 10)
//len 代表没有被读取的元素数, cap 代表整个通道的容量
fmt.Println(len(c)) //0
fmt.Println(cap(c)) //10
WaitingGroup组件
Add(10) 给内置计数器加10
Done() 相当于Add(-1)
Wait() 内置计数器不为0则一直等待
// 写法
func main() {
var wg sync.WaitGroup
wg.Add(10)
for i := 0; i < 10; i++ {
go func(i int) {
defer wg.Done()
fmt.Println(i)
time.Sleep(time.Millisecond * 3000)
}(i)
}
wg.Wait()
fmt.Println("done")
}
select
- 先打乱所有的case语句
- 遍历case语句,查看是否已经读写了
- 选择可读写的case去执行
- 没有可读写的case,则查看default语句是否定义,再去执行
- 没有defaul语句,则会等待可执行的case
看一段融合了并发,缓冲,退出通知等多重特性的代码
func GenerateA(done chan struct{}) chan int {
ch := make(chan int, 5)
// fmt.Println("通道数+1")
go func() {
fmt.Println("线程数+A")
Label:
for {
select {
case res := <-done:
fmt.Println("done", res)
break Label
case ch <- rand.Int():
}
}
close(ch)
}()
return ch
}
func GenerateB(done chan struct{}) chan int {
ch := make(chan int, 5)
go func() {
fmt.Println("线程数+B")
Label:
for {
select {
case res := <-done:
fmt.Println("done", res)
break Label
case ch <- rand.Int():
}
}
close(ch)
}()
return ch
}
func GenerateInt(done chan struct{}) chan int {
//无缓冲通道
ch := make(chan int)
send := make(chan struct{})
go func() {
Label:
for {
select {
case <-done:
send <- struct{}{}
send <- struct{}{}
break Label
case ch <- <-GenerateA(send):
fmt.Println("chose A")
case ch <- <-GenerateB(send):
fmt.Println("chose B")
}
}
close(ch)
}()
return ch
}
func main() {
done := make(chan struct{})
ch := GenerateInt(done)
fmt.Println(runtime.NumGoroutine())
for i := 0; i < 10; i++ {
fmt.Println(<-ch)
}
fmt.Println(runtime.NumGoroutine())
done <- struct{}{}
fmt.Println("stop gernate", struct{}{})
time.Sleep(1 * time.Second) //等待1s,让停止的goruntime打印,如果不加这句话,可能会导致主线程比新起的协程早退出,从而无法打印出done {}
}
打印结果不展示,其中发现的问题:
1.打印出来的数字长度不固定
2.每次Select查看case是否堵塞的时候,都会执行一次该方法
Context
func main() {
ctxa, cancel := context.WithCancel(context.Background())
go work(ctxa, "work1")
tm := time.Now().Add(3 * time.Second)
ctxb, _ := context.WithDeadline(ctxa, tm)
go work(ctxb, "work2")
oc := OtherContext{ctxb}
ctxc := context.WithValue(oc, "key", "andes, pass from main")
go workWithValue(ctxc, "work3")
time.Sleep(10 * time.Second)
cancel()
time.Sleep(5 * time.Second)
fmt.Println("main stop")
}
type OtherContext struct {
context.Context
}
func work(ctx context.Context, name string) {
for {
select {
case <-ctx.Done():
fmt.Printf("%s get msg to cancel\n", name)
return
default:
fmt.Printf("%s is running \n", name)
time.Sleep(1 * time.Second)
}
}
}
func workWithValue(ctx context.Context, name string) {
for {
select {
case <-ctx.Done():
fmt.Printf("%s get msg to cancel\n", name)
return
default:
value := ctx.Value("key").(string)
fmt.Printf("%s is running value=%s \n", name, value)
time.Sleep(1 * time.Second)
}
}
}
这段代码中,都是一条链路下来的
根节点 context.Background() -> ctxa -> ctxb -> oc
其中ctxa加了个时间控制,所以到达一定的时间就会自动关闭
oc附带了个键对值
Go基础知识梳理(四)的更多相关文章
- [SQL] SQL 基础知识梳理(四) - 数据更新
SQL 基础知识梳理(四) - 数据更新 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5929786.html 序 这是<SQL 基础知识梳理( ...
- [SQL] SQL 基础知识梳理(一)- 数据库与 SQL
SQL 基础知识梳理(一)- 数据库与 SQL [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5902856.html 目录 What's 数据库 ...
- [SQL] SQL 基础知识梳理(三) - 聚合和排序
SQL 基础知识梳理(三) - 聚合和排序 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5926689.html 序 这是<SQL 基础知识梳理 ...
- [SQL] SQL 基础知识梳理(五) - 复杂查询
SQL 基础知识梳理(五) - 复杂查询 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5939796.html 序 这是<SQL 基础知识梳理( ...
- C#基础知识梳理索引
C#基础知识梳理索引 一 引子 之前曾写了一篇随笔<.NET平台技术体系梳理+初学者学习路径推荐+我们的愿景与目标> 三个月过去了,目标使更多的编程初学者,轻松高效地掌握C#开发的基础,重 ...
- [SQL] SQL 基础知识梳理(六)- 函数、谓词、CASE 表达式
SQL 基础知识梳理(六)- 函数.谓词.CASE 表达式 目录 函数 谓词 CASE 表达式 一.函数 1.函数:输入某一值得到相应输出结果的功能,输入值称为“参数”,输出值称为“返回值”. 2. ...
- [SQL] SQL 基础知识梳理(七)- 集合运算
SQL 基础知识梳理(七)- 集合运算 目录 表的加减法 联结(以列为单位) 一.表的加减法 1.集合:记录的集合(表.视图和查询的执行结果). 2.UNION(并集):表的加法 -- DDL:创建表 ...
- Linux基础知识梳理
Linux基础知识梳理 Linux内核最初只是由芬兰人林纳斯?托瓦兹(Linus Torvalds)在赫尔辛基大学上学时出于个人爱好而编写的.Linux是一套免费使用和自由传播的类Unix操作系统,是 ...
- MySQL 基础知识梳理
MySQL 的安装方式有多种,但是对于不同场景,会有最适合该场景的 MySQL 安装方式,下面就介绍一下 MySQL 常见的安装方法,包括 rpm 安装,yum 安装,通用二进制安装以及源码编译安装, ...
随机推荐
- pycharm 安装插件
1.使用pip安装插件 pip安装指定版本的插件: pip install openpyxl==2.6.2 -i https://pypi.doubanio.com/simple/ -i后面跟的是&q ...
- vue之Better-Scroll组件 将滚动条滚到最底部
首先我们需要使用scrollTo这个方法: scrollTo(x, y, time, easing) 参数: {Number} x 横轴坐标(单位 px) {Number} y 纵轴坐标(单位 px) ...
- HowToDoInJava Java 教程·翻译完成
原文:HowToDoInJava 协议:CC BY-NC-SA 4.0 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远. ApacheCN 学习资源 目录 核心 Java 教程 什 ...
- [论文][半监督语义分割]Adversarial Learning for Semi-Supervised Semantic Segmentation
Adversarial Learning for Semi-Supervised Semantic Segmentation 论文原文 摘要 创新点:我们提出了一种使用对抗网络进行半监督语义分割的方法 ...
- Mysql一个主一备
Mysql主从复制 -- 一主一备 主从复制原理: Mysql的主从复制是mysql本身自带的一个功能,不需要额外的第三方软件可以实现,其复制功能并不是copy文件实现的,而是借助binlog日志文件 ...
- js中全局变量和局部变量以及变量声明提升
javascript中全局变量和局部变量的区别 转载前端小99 发布于2018-04-23 15:31:35 阅读数 2102 收藏 展开 [javascript] view plain copy ...
- 使用df -h命令查看磁盘空间使用率不算高,还有很多空余空间,但是创建文件或写入数据时一直报错磁盘写满
关于磁盘空间中索引节点爆满的问题还是挺多的,借此跟大家分享一下: 一.发现问题 在公司一台配置较低的Linux服务器(内存.硬盘比较小)的/data分区内创建文件时,系统提示磁盘空间不足,用df -h ...
- 用Java开发局域网内文件传输软件遇到的一些问题
项目地址:https://github.com/b84955189/FileTransfer 由于巨懒的我不太喜欢使用U盘操作文件,特此开发一个简易的文件传输程序. 目前仅限局域网内传输,后期会尝试写 ...
- vue 中 使用 element-ui 发送请求前 校验全部表单,报警告: [Element Warn][Form]model is required for validate to work!
WEB先生 2020-07-14 20:01:45 754 收藏 分类专栏: vue 文章标签: vue js 版权 报这种错可能有以下两种情况 1.属性绑定错误,确保绑定的是 :model ...
- VMware15.5虚拟机安装及LInux系统安装前 准备工作
VMware15.5虚拟机安装及Linux系统安装前 准备工作 一.vmware15.5安装 1.安装环境准备 1.vmware15.5版本和秘钥(版本资源和密钥小白已经上传到资源文档里面,要想下载可 ...