在学习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通道阻塞模式的更多相关文章

  1. 【解决了一个小问题】golang protocol buffers 3中去掉json标签中的omitempty

    参考了这篇帖子:golang protobuf从生成的json标记中删除omitempty标记 由于是在windows上开发,因此写了一个python脚本来解决: remove_tag.py impo ...

  2. 【解决了一个小问题】golang build中因为缓存文件损坏导致的编译错误

    编译的过程中出现了一个吓人的错误: GOROOT=C:\Go #gosetup GOPATH=C:\Users\ahfuzhang\go #gosetup C:\Go\bin\go.exe mod t ...

  3. 【解决了一个小问题】golang gin框架中的模板,让模板中的参数不要做HTML转义

    代码中使用了类似的方式来向模板填充参数: c.HTML(200, "list.html", gin.H{"data":builder.String()}) 模板 ...

  4. 【解决了一个小问题】golang的go.mod中出现版本错误

    代码中的这一句使用prometheus2.28.0版本的代码: import "github.com/prometheus/prometheus/prompb" 我把require ...

  5. 【解决了一个小问题】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中出现如下提示: ...

  6. 【解决了一个小问题】golang samara的kafka客户端中使用错误版本号导致初始化失败

    发现在如下代码中存储kafka生产者初始化失败: config.Version = sarama.V0_10_2_1 //V2_2_0_0 producer, err := sarama.NewSyn ...

  7. 【解决了一个小问题】golang xorm中使用where id in (xxx),没办法使用参数替换

    代码中使用XORM来从数据库查询数据,有类似如下的代码: session.Where("id in (?)", strings,Join(arr, ",")) ...

  8. 【解决了一个小问题】golang go.mod中多了一个斜杠导致replace无效

    replace github.com/sxxx/common_lib/src/ => ../../common_lib/src 修改成 replace github.com/sxxx/commo ...

  9. MVVM模式的一个小例子

    使用SilverLight.WPF也有很长时间了,但是知道Binding.Command的基本用法,对于原理性的东西,一直没有深究.如果让我自己建一个MVVM模式的项目,感觉还是无从下手,最近写了一个 ...

随机推荐

  1. BootStrap 关于input与btn的点击focus取消特效相关css

    取消btn按钮点击出现的外边框: .btn:focus, /*清除btn按钮点击出现的边框*/.btn:active:focus,.btn.active:focus,.btn.focus,.btn:a ...

  2. redis 事务(悲观锁和乐观锁)

    MULTI 开启事务,后续的命令会被加入到同一个事务中 事务中的操作会发送给客服端,但是不会立即执行,而是将操作放到了该事务对应的一个队列中,服务端返回QUEQUD EXEC 执行EXEC后,事务中的 ...

  3. SpringBoot与数据层

    1.JDBC <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...

  4. 什么是StatefulSet

    简单说来,StatefulSet其实就是一种升级版的Deployment,大体工作原理如下 1.为每个Pod名字按顺序编号,按顺序启动 # kubectl get po -o wide -l app= ...

  5. Geohash精度和原理

    转自:https://blog.csdn.net/u011497262/article/details/81210634 https://www.jianshu.com/p/1ecf03293b9a ...

  6. 练手爬虫用urllib模块获取

    练手爬虫用urllib模块获取 有个人看一段python2的代码有很多错误 import re import urllib def getHtml(url): page = urllib.urlope ...

  7. Vue.js2.0快速入门笔记

    vue.js 解耦视图与数据,可复用的组件,前端路由,状态管理,虚拟DOM. MVVM模式:当View(视图层)变化时,会自动更新ViewModel(视图模型),View与ViewModel之间双向绑 ...

  8. ABAP 字符串换行符处理

    今天发现BW系统从K3系统数据库抽取会计科目的描述时,转换出错. 从监控器上看是值2KO 845 412D#有问题,但不知道有什么问题,检查后感觉是符号#的问题. 在转换中添加代码,替换#,发现没有起 ...

  9. Java中如何判断一个字符是否是字母或数字

    使用Java中Character类的静态方法: Character.isDigit(char c) //判断字符c是否是数字字符,如‘1’,‘2’,是则返回true,否则返回false   Chara ...

  10. Linux数据库的创建 导入导出 以及一些基本指令

    首先linux 下查看mysql相关目录 查看 mysql 的安装路径 执行查询 SQL mysql>show variables like '%dir%'; datadir 就是数据路径 确定 ...