golang管道
golang中的channel
channel用于goroutine之间的通信
如果不用channel,使用共享全局变量的方式,需要加锁
// synchornized 同步
// golang中的 sync包中有互斥锁
var lock sync.Mutex // mutex 互斥
lock.Lock() // 上锁
// 多个goroutine同时对相同的数据进行修改
lock.Unlock() // 解锁
使用同步锁并发效率会很低
channel主要用于goroutine通信和解决主线程等待goroutine执行结束再退出的问题
basic concept of channel
- 本质上是一个FIFO的数据结构-队列
- 线程安全,不需要加锁
- channel是有类型的,如字符串channel
chan string
,只能保存string数据
declare channel
var variableName chan dataType
var c1 chan int
var c2 chan bool
var c3 chan map[int]string
channel 是引用类型,必须初始化后才能使用
var c1 chan int
c1 = make(chan int, 4) // 使用make函数初始化chan int, 4是容量
// 初识化之后容量不可动态变化,channel不会自动扩容,写入数据时不能超过容量,否则会deadlock
// fatal error: all goroutines are asleep - deadlock!
c1 <- 666 // 写入数据
num := <- c1 // 取出数据, 每取一个数据,channel长度减一
// 不使用goroutine的情况下
// 当数据全部取出是再对channel取数据会报 deadlock
使用channel的注意事项
- 只保存指定类型数据
- 数据满后,不能在添加数据,否则deadlock
- 从channel中取出数据,长度减一,腾出一个位置可添加数据
- 不使用goroutine的情况下,当数据全部取出是再对channel取数据会报 deadlock
channel的遍历和关闭
内置函数close(channel) 可以关闭channel,不能再添加数据,但是可以读取数据
channel可以用for range方式遍历
但是必须是已关闭的channel
for range遍历一个未关闭的channel会出现deadlock
c1 := make(chan int, 10)
for i:=0; i<10; i++ {
c1 <- i
}
close(c1)
for v := range c1 {
fmt.Println(v)
}
对于一个已关闭的channel读取数据时,如果数据已全部取出,取值状态返回false而不会报错
func main() {
c1 := make(chan int, 2)
c1 := make(chan int, 2)
c1 <- 1
c1 <- 2
c2 <- 1
c2 <- 2
close(c1)
<- c1 // 取出值 丢弃不用 1
<- c1 // 2
v, ok := <-c1 // 数据已取完
fmt.Println(v,ok) // 0 false
<- c2 // 1
<- c2 // 2
v, ok := <-c2 // 数据已取完 程序到这里会出错 deadlock
fmt.Println(v,ok)
}
对于已关闭的管道,可以在取完数据时结束等待goroutine执行
for {
_, ok := <- exitChan bool
if !ok {
break
}
}
未关闭的channel需要取出指定个数的值之后结束等待goroutine执行
channel使用细节
channel默认是既可以读又可以写的
可以声明为只读或只写
var c1 <- chan int // 只读
var c2 chan <- int // 只写
一般channel不会声明为只读和只写,而是在声明函数形参的时候使用
var c1 chan string
func sendData(c chan <- string) {...}
func readData(c <- chan string) {...}
// c1是默认可读可写的channel
// 当c1作为参数传给 sendData时 在 sendData 函数中只允许对管道进行写操作
// 当c1作为参数传给 readData时 在 readData 函数中只允许对管道进行读操作
goroutine中使用recover函数解决协程中出现的panic ,不影响主线程的执行
defer func() {
if err = recover(); err != nil {
...dosomething
}
}
select
select用于解决从管道中取数据的阻塞问题
不使用select,在遍历未关闭的管道时会deadlock
然而,很多情况下管道都是未关闭的,因为不好确定什么时候关
用select来遍历未关闭管道,不会deaklock
func main() {
c1 := make(chan int, 10)
c2 := make(chan string, 5)
for i := 0; i < 10; i++ {
rand.Seed(time.Now().UnixNano())
c1 <- rand.Intn(100)
}
c2 <- "commerce"
c2 <- "corresponding"
c2 <- "oblige"
c2 <- "decline"
c2 <- "praise"
label1:
for {
select {
case v := <-c1:
fmt.Println(v)
case v := <-c2:
fmt.Println(v)
default:
fmt.Println("两个管道都没数据了吧")
break label1
}
}
fmt.Println("adhere")
}
golang管道的更多相关文章
- golang 管道
2.管道简介Golang的原子并发特性使得它很容易构造流数据管道,这使得Golang可有效的使用I/O和多CPU特性.本文提出一些关于管道的示例,在这个过程中突出了操作失败的微妙之处和介绍处理失败的具 ...
- golang中管道热替换
golang中管道替换问题 https://blog.csdn.net/cyk2396/article/details/78875347 1.运行以下代码: var chan1 chan int va ...
- golang channle 管道
管道的使用介绍 现在要计算 1-N 的各个数的阶乘,并且把各个数的阶乘放入到 map 中.最后显示出来.要求使用 goroutine 完成 package main import ( "fm ...
- Golang, 以17个简短代码片段,切底弄懂 channel 基础
(原创出处为本博客:http://www.cnblogs.com/linguanh/) 前序: 因为打算自己搞个基于Golang的IM服务器,所以复习了下之前一直没怎么使用的协程.管道等高并发编程知识 ...
- channel Golang
Golang, 以17个简短代码片段,切底弄懂 channel 基础 (原创出处为本博客:http://www.cnblogs.com/linguanh/) 前序: 因为打算自己搞个基于Golang的 ...
- Golang 语法学习笔记
Golang 语法学习笔记 包.变量和函数. 包 每个 Go 程序都是由包组成的. 程序运行的入口是包 main. 包名与导入路径的最后一个目录一致."math/rand" 包由 ...
- 【GoLang】golang 的精髓--流水线,对现实世界的完美模拟
直接上代码: package main import ( "fmt" "runtime" "strconv" "sync" ...
- PHP与Golang如何通信?
PHP与Golang如何通信? 最近遇到的一个场景:php项目中需要使用一个第三方的功能(结巴分词),而github上面恰好有一个用Golang写好的类库.那么问题就来了,要如何实现不同语言之间的通信 ...
- 【GoLang】并发小结
006.并发 1 概念 1.1 goroutine是Go并行设计的核心,goroutine的本质是轻量级线程 1.2 golang的runtime实现了对轻量级线程即goroutine的智能调度管理 ...
随机推荐
- 2013第四届蓝桥杯C/C++ B组
题目标题: 高斯日记:Excel 大数学家高斯有个好习惯:无论如何都要记日记. 他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210 后来人们知道,那个整数就是日期,它表示 ...
- Webstorm使用时发生Page 'http://localhost:63340/n…tok/css/bootstrap.css.map' requested without authorization, you can copy URL and open it in browser to trust it.
在使用webstorm编辑器开发时候,点击4处发生以下错误: Page 'http://localhost:63340/n…tok/css/bootstrap.css.map' requested w ...
- Vue 实例详解与生命周期
Vue 实例详解与生命周期 Vue 的实例是 Vue 框架的入口,其实也就是前端的 ViewModel,它包含了页面中的业务逻辑处理.数据模型等,当然它也有自己的一系列的生命周期的事件钩子,辅助我们进 ...
- Beta发布 _thunder_文案+美工展示
作业要求:https://edu.cnblogs.com/campus/nenu/SWE2017FALL/homework/1366 团队介绍:thunder 组成员及各位博客地址: 1.王航:htt ...
- Beta发布文案+美工
团队名称:探路者 1蔺依铭:http://www.cnblogs.com/linym762/(组长) 2张恩聚:http://www.cnblogs.com/zej87/ 3米赫:http://www ...
- oracle将多个结果集用逗号拼接成字符串
有两个函数wmsys.wm_concat和listagg 1,SELECT wmsys.wm_concat(CATALOG_NAME) FROM "DATASHARE"." ...
- 初学Cocos2dx
初学cocos2dx Cocos2dx 中的主要概念包括:应用.导演.场景.层.精灵.动画.动作. Cocos2dx里面的主要类 1.CCObject Object Object Object 是co ...
- 《Spring1之第三次站立会议》
<第三次站立会议> 昨天:我对自己找到的代码进行了相关的了解后,把它们在编译环境中进行了编译以及接着对代码进行逐步深入了解: 今天:我把小组成员找到的写关于登录界面的代码加到了我的项目工程 ...
- Linux手动添加系统环境共享库路径
1.在以下目录 #/etc/ld.so.conf.d 添加相应的xxx.conf 2.写入所要共享库的路径 如:/usr/lib/ 3.导入共享库配置 $ldconfig
- 项目Beta冲刺(团队)随笔集
凡事预则立 项目Beta冲刺准备 第一天 项目Beta冲刺(团队)第一天 第二天 项目Beta冲刺(团队)第二天 第三天 项目Beta冲刺(团队)第三天 第四天 项目Beta冲刺(团队)第四天 第五天 ...