一个小事例,了解golang通道阻塞模式
在学习golang中,channel真的是让人捉摸不透的东西,本来我自以为我理解了协程阻塞的用法了,结果就下面这个小例子,我还是在打印输出后才搞明白到底怎么回事?
当然了,这也是我自身对协程这块不太熟造成的呀,另外,学习还真不能想当然,尤其是编程这块,真是要多实践,有时候你不经意的一点小举动,可能都会让你学到东西,甚至让你受益非浅的。
下面就是那个小例子,通过输出调试看结果后,也让我比以前更了解这个channel阻塞模式了。
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
var printChar chan int
func prinNums() {
defer wg.Done()
for i:=0;i < 2; i++ {
printChar <- 1111
fmt.Println(<-printChar)
}
}
func printChars(){
defer wg.Done()
for i:=0;i < 2; i++ {
fmt.Println("阻1")
fmt.Println(<-printChar)
fmt.Println("阻2")
fmt.Println("出来1")
printChar <- 1222
fmt.Println("出来2")
}
}
func main(){
printChar = make(chan int)
wg.Add(2)
go prinNums()
go printChars()
wg.Wait()
}
输出结果为:
阻1
1111
阻2
出来1
1222
出来2
阻1
1111
阻2
出来1
1222
出来2
看完结果,再仔细分析下就基本明白了。
其实,我最开始是在channel赋值和输出这里犯糊涂了,一直没理解到,比如printNums函数这里
printChar <- 1111
fmt.Println(<-printChar)
我开始想当然的以为直接赋值后,然后就能直接取值了。这就是没理解协程阻塞和调度。当执行到 printChar <- 1111 这里时,因为是阻塞模式,那么它必须等待其它协程将它里面的数据取走,它后面的代码也不会执行,就类似于php的yield,它将按制权让出来给其它的协程。
其它协程将channel里面的值取出来后,继续执行协程阻塞前的那些代码,对比以上的输出就很容易看出来了。
当然了,如果是懂的人,我这个会让人笑掉大牙,但是没关系,这也是我自已自学习路上学到的东西,这就够了。
一个小事例,了解golang通道阻塞模式的更多相关文章
- 【解决了一个小问题】golang protocol buffers 3中去掉json标签中的omitempty
参考了这篇帖子:golang protobuf从生成的json标记中删除omitempty标记 由于是在windows上开发,因此写了一个python脚本来解决: remove_tag.py impo ...
- 【解决了一个小问题】golang build中因为缓存文件损坏导致的编译错误
编译的过程中出现了一个吓人的错误: GOROOT=C:\Go #gosetup GOPATH=C:\Users\ahfuzhang\go #gosetup C:\Go\bin\go.exe mod t ...
- 【解决了一个小问题】golang gin框架中的模板,让模板中的参数不要做HTML转义
代码中使用了类似的方式来向模板填充参数: c.HTML(200, "list.html", gin.H{"data":builder.String()}) 模板 ...
- 【解决了一个小问题】golang的go.mod中出现版本错误
代码中的这一句使用prometheus2.28.0版本的代码: import "github.com/prometheus/prometheus/prompb" 我把require ...
- 【解决了一个小问题】golang中引用一个路径较长的库,导致goland中出现"module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v2"
在项目中的go.mod文件中有这样一句: require ( github.com/xxx-devops/xx1/sdk/go v2.2.3 ) 项目的编译没有问题,但是goland中出现如下提示: ...
- 【解决了一个小问题】golang samara的kafka客户端中使用错误版本号导致初始化失败
发现在如下代码中存储kafka生产者初始化失败: config.Version = sarama.V0_10_2_1 //V2_2_0_0 producer, err := sarama.NewSyn ...
- 【解决了一个小问题】golang xorm中使用where id in (xxx),没办法使用参数替换
代码中使用XORM来从数据库查询数据,有类似如下的代码: session.Where("id in (?)", strings,Join(arr, ",")) ...
- 【解决了一个小问题】golang go.mod中多了一个斜杠导致replace无效
replace github.com/sxxx/common_lib/src/ => ../../common_lib/src 修改成 replace github.com/sxxx/commo ...
- MVVM模式的一个小例子
使用SilverLight.WPF也有很长时间了,但是知道Binding.Command的基本用法,对于原理性的东西,一直没有深究.如果让我自己建一个MVVM模式的项目,感觉还是无从下手,最近写了一个 ...
随机推荐
- 以太坊智能合约开发 Solidity学习
1. pragma solidity >=0.4.22 <0.6.0;//版本号,头文件 contract BooleanTest { bool _a;//默认返回false int nu ...
- 文件批量生成IO流读写
/// <summary> /// 生成文件的 /// </summary> /// <param name="calssName"></ ...
- PlayJava Day016
今日所学: /* 2019.08.19开始学习,此为补档. */ 数组 1.一维数组:数据类型[ ] 变量名 = new 数据类型[长度] 获取长度:array.length 在使用下标时确保不超过a ...
- PDF转换成DXF文件?PDF转DXF的操作方法
在CAD工作中,经常就需要将绘制完成的图纸文件的格式进行转换,那怎么将PDF文件转换成DXF格式的呢?具体要怎么来进行操作呢?本编教程小编就来教教大家具体操作方法,具体操作如下: 一.工具转换 推荐指 ...
- CSAPP 2-1 - 信息的存储
目录 0 基础概念及摘要 1 信息存储 1.1 十六进制表示法 1.2 字数据大小 1.3 寻址和字节顺序 0 基础概念及摘要 (1) 基础概念: 现代计算机存储和处理的信息以二进制信号表示 -- 0 ...
- Centos7_防火墙的常用配置(杂记)
Centos6和Centos7防火墙的区别 使用的工具不一样,Centos6使用的是Iptables而Centos7使用的则是Firewall Iptables,用于过滤数据包,属于网络层防火墙 Fi ...
- Linux 和 Windows 查看 CUDA 和 cuDNN 版本
目录 Linux 查看 CUDA 版本 查看 cuDNN 版本 Windows 查看 CUDA 版本 查看 cuDNN 版本 References Linux 查看 CUDA 版本 方法一: nvcc ...
- Linux 和 Windows 查看当前运行的 python 进程及 GPU、CPU、磁盘利用率
目录 查看当前 python 进程 Linux Windows 查看 GPU 利用率 Linux Windows Linux CPU 利用率 Linux 磁盘利用率 查看当前 python 进程 Li ...
- 201871010101-陈来弟《面向对象程序设计(java)》第一周学习总结
项目 内容 这个作业属于哪个课程 <任课教师博客主页链接>https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 <作业链接地址>http ...
- linux下的set, export, env的区别
set和export的区别 set可以用来显示所有变量的值,而export能将一个变量导出,在其子shell或子进程也可见 export和env的区别 两者的作用是一样的,只是env是一个外部工具 基 ...