Golang 协程的使用方法
Golang 协程正确的使用方法
错误的使用方法
package main
// 错误使用案例
import ("time""fmt"
)
var c1 chan string = make(chan string)
func main(){func(){time.Sleep(time.Second * 2)c1 <- "result 1"}()fmt.Println("c1 is", <-c1)
}
由于 c1
在创建时没有指定缓存长度, 所以在写入channel c1
时,必须应该有对应的接收端在等待,上例中,由于对c1
的写入时c1
没有缓存区且没有接收端,所以就报错了。
fmt.Println("c1 is", <-c1)
这段代码本来是可以阻塞的,但是这种用法是错误的
正确的使用方法 (将写入放到单独的协程中)
通过将写入端放到单独的协程中,使得channel 的写入端和接收端可以对接。
// ....
func main(){go func(){time.Sleep(time.Second * 2)c1 <- "result 1"}()fmt.Println("I am here")fmt.Println("c1 is", <-c1)
}
可以看到 匿名函数部分代码是在独立的协程中执行的,在同一个协程中对一个channel写入时,如果channel 没有缓存长度,必然会报错,见错误案例
select 用法
select 可以同时监听多个channel
阻塞方式的
执行到select 语句时如果所有的case 中的channel 都没有数据,select 语句将会阻塞,直到一个case中的 channel 获取到数据。
package main
import ("time""fmt"
)func AskX(bid1 chan int) {for i:=100 ;i<105 ; i++{time.Sleep(time.Second*1)bid1 <- i}
}
func AskY(bid2 chan int) {for i:=0 ; i<5; i++{time.Sleep(time.Second*2)bid2 <- i}}func main(){bid1 := make(chan int)bid2 := make(chan int)go AskX(bid1)go AskY(bid2)select {case Xbid := <-bid1:fmt.Println(Xbid)case Ybid := <-bid2:fmt.Println(Ybid)}
}
运行的结果是,代码被阻塞 1秒后输出 100
, 因为channel bid1
在1秒后拿到了数据,select 阻塞结束输出
不阻塞的
将阻塞部分 select 处代码修改为
select {case Xbid := <-bid1:fmt.Println(Xbid)case Ybid := <-bid2:fmt.Println(Ybid)default :fmt.Println("no data.")}
可以看到只添加了 default
语句,表示当所有的 channel 都取不到数据时,默认执行 default
后面的语句
带超时机制的
select {case Xbid := <-bid1:fmt.Println(Xbid)case Ybid := <-bid2:fmt.Println(Ybid)case <-time.After(time.Second*2):fmt.Println("overtime for 2 seconds")}
上面的代码表示,当所有channel 超过2秒还没有取到数据,就会执行超时设置部分的代码。
总结
在同一个协程中如果对一个channel写入数据,如果channel 没有缓存长度,必然报错
在主协程中有接收端,在子协程中没有发送端会报错
在子协程中有发送端,在其他协程中没有接收端,不会报错
转载请注明:大后端 » Golang 协程正确的使用方法
Golang 协程的使用方法相关推荐
- golang 协程同步 简介
目录 协程概念简要理解 为什么要做同步 协程的几种同步方法 Mutex channel WaitGroup 协程概念简要理解 协程类似线程,是一种更为轻量级的调度单位,但协程还是不同于线程的,线程是系 ...
- golang 数组 最后一个_面试必问:Golang高阶Golang协程实现原理
1 01 引言 实现并发编程有进程,线程,IO多路复用的方式.(并发和并行我们这里不区分,如果CPU是多核的,可能在多个核同时进行,我们叫并行,如果是单核,需要排队切换,我们叫并发). 1.1 进程和 ...
- go 怎么等待所有的协程完成_怎么关闭golang协程
怎么关闭golang协程 发布时间:2020-06-10 10:43:33 来源:亿速云 阅读:284 作者:Leah 这篇文章给大家分享的是关闭golang协程的方法.小编觉得挺实用的,因此分享给大 ...
- 深入浅出 Golang 协程池设计
使用Go语言实现并发的协程调度池阉割版,本文主要介绍协程池的基本设计思路,目的为深入浅出快速了解协程池工作原理,与真实的企业协程池还有很大差距,本文仅供学习参考. 一.何为并发,Go又是如何实现并发? ...
- GoLang协程与通道---下
GoLang协程与通道---下 新旧模型对比:任务和worker 惰性生成器的实现 实现 Futures 模式 复用 典型的客户端/服务器(C/S)模式 卸载(Teardown):通过信号通道关闭服务 ...
- golang协程分段下载文件
目录 golang协程 加锁示例 golang协程分段下载文件 golang协程 golang协程分段下载文件,为了提升性能,更好的利用golang协程的特性,我们开始使用他测试一下我们的程序 gol ...
- Python与Golang协程异同
背景知识 这里先给出一些常用的知识点简要说明,以便理解后面的文章内容. 进程的定义: 进程,是计算机中已运行程序的实体.程序本身只是指令.数据及其组织形式的描述,进程才是程序的真正运行实例. 线程的定 ...
- Python 中 异步协程 的 使用方法介绍
静觅 崔庆才的个人博客:Python中异步协程的使用方法介绍:https://cuiqingcai.com/6160.html Python 异步 IO .协程.asyncio.async/await ...
- Golang 协程顺序打印
Golang 协程顺序打印 A.B 两个协程分别打印 1.2.3.4 和 A,B,C,D 实现:定义 A.B 两个 channal,开 A.B 两个协程,A 协程输出[1, 2, 3, 4].B 协程 ...
最新文章
- C/C++中extern关键字详解
- Datawhale组队学习周报(第018周)
- eclipse 打开文件目录
- VTK:动轴用法实战
- 0 开场白元素项类的设计
- Pytest入门【1】
- scrapy爬虫实战分享
- 洛谷 刷题 深基部分题解(python版)-2022.01.29
- 01-jbpm工作流实现
- 读文万卷025期:使用MRI形态学特征和表观弥散系数预测WHO II/III级胶质瘤分子状态;帕金森病的中脑的定量磁敏感成像
- matlab中通过滤波器,[转载]matlab 滤波器(转)
- 企鹅撞冰块Java游戏_亲子桌面游戏玩具 拯救企鹅敲打冰块玩法
- Trie Tree和Radix Tree
- 微信公众号网页授权域名和JS接口安全域名配置攻略
- C算法之一元二次方程组的解
- 带劲!厂内全流程智能仓储物流系统
- python获取所有a股股票代码_股票量化分析(一)获取A股列表
- 1128_AURIX_TC275的基本参数了解
- Protobuf—简介,优缺点
- JS 各类验证(手机号验证、邮箱验证、身份证验证...)