一个小事例,了解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模式的项目,感觉还是无从下手,最近写了一个 ... 
随机推荐
- Java大数类 BigInteger
			package bigint; /** * This class encapsulates a BigInteger, i.e. a positive or negative integer * wi ... 
- C 语言输出不同颜色字体
			C 语言输出不同颜色字体 \033是8进制,它就是unix下终端转义符ESC(16进制1A,10进制27) ESC[xm 是unix下改变终端输出颜色的命令 所以,如果是红色,则我们定义为\033[0 ... 
- vue template标签
			在普通的html里面: template标签默认有个 display:none; 属性,并且其里面的内容是不可见的. 在vue里面: template标签类似一个隐藏的div,在审查元素的时候是找不到 ... 
- 【构建之法教学项目】一个简单的基于C#的电子商务系统演练场景的代码示例
			电子商务平台,是一个历史悠久而又充满挑战的行业,他和社交一起成为中国互联网市场的两极.电子商务系统是一个非常复杂的系统,他实现了人与物.人与人的链接,同时也需要大量的技术来支撑,实现系统的高可用.这些 ... 
- SSH框架之Hibernate第一篇
			1.2Hibernate的概述: 1.2.1 什么Hibernate? Hibernate(开发源代码的对象关系映射框架)是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它 ... 
- Vue结合后台导入导出Excel问题详解
			话不多说,直接上前端代码 axios({ method: 'post', url: 'http://localhost:19090/exportUser',//这个是请求的地址 params: {// ... 
- javaweb 复习随笔
			js和jsp区分: js是一种脚本语言,常运行在前台和客户端交互,不会给服务器带来负担,可以更好的修饰静态页面 jsp可以说是servlet的一种,jsp会先翻译,翻译成Servlet执行,运行在服务 ... 
- iOS 中UICollectionView实现各种视觉效果
			参考链接:https://www.jianshu.com/p/b3322f41e84c 基础:https://www.jianshu.com/p/d0b034f59020 
- 【React Native】在原生和React Native间通信(RN调用原生)
			一.从React Native中调用原生方法(原生模块) 原生模块是JS中也可以使用的Objective-C类.一般来说这样的每一个模块的实例都是在每一次通过JS bridge通信时创建的.他们可以导 ... 
- Command CompileSwiftSources failed with a nonzero exit code
			Xcode错误提示:Command CompileSwiftSources failed with a nonzero exit code,网上找了好多才搞定,通过在Build Setting里面自添 ... 
