博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
go使用chan的几个场合
阅读量:3588 次
发布时间:2019-05-20

本文共 2086 字,大约阅读时间需要 6 分钟。

go中chan有两个概念,无缓冲和有缓冲,定义如下:

遇到的问题1:

问题描述:有一些场合要并行处理,但是在并行处理的过程中,需要通过某些返回值来判断协程是否结束。

比如:使用ffmpeg处理视频的过程中,需要一边下载视频并将下载的视频截帧,并同时将截取的图片帧用作其他处理,这两者要并行处理。并且在下载视频,截取图片帧的同时,还要同时起另外一个协程处理相关的音频操作

解决办法:使用chan

1:定义一个processVideo函数,起一个协程调用该函数,并同时定义一个processAudio函数,并且起一个协程调用该函数

func main() {

processvideochan := make(chan error, 1)

processaudiochan := make(chan error, 1)

var err error

go this.processVideo(processvideochan)

go this.processAudio(processaudiochan)

 

if err = <-processaudiochan; err != nil {

return

}

if err = <-processvideochan; err != nil {

return

}

}

在上面processVideo和processAudio函数中,我们可以通过对chan变量赋值来判断协程是否结束,如果一直没有对两个变量赋值,则在主线程中会一直卡住。同时我们可以根据该参数判断是否有错误产生。

测试该功能小程序:

func gggg(processaudiochan chan<- int) {

time.Sleep(time.Second*5)

processaudiochan <- 1

}

func main() {

processaudiochan := make(chan int, 1)

go gggg(processaudiochan)

<- processaudiochan

fmt.Println("--------------------------->>>")

}

 

遇到的问题2:

问题描述:需要定义一个不确定大小的数组,根据视频截取出来的帧的个数,来确定数组的大小,对截取出来的图片会进行处理,将进行处理之后的结果放到数组中,由于对图片进行处理可能耗时比较长,所以对图片进行处理是并行操作的。

解决办法:一个协程定义一个切片,另外对图片进行处理的协程,将处理后的结果放入切片中。

测试功能小程序:

func tttt(imageresult *int) {

time.Sleep(time.Second)

*imageresult = 100

}

 

func main() {

var imageresult []*int

for i:=0; i<2;i++ {

var imgresult int = 10

go tttt(&imgresult)

time.Sleep(time.Second)

fmt.Println("imageresult---:", imgresult)

imageresult = append(imageresult,&imgresult)

}

time.Sleep(time.Second*2)

fmt.Println("imageresult:", *imageresult[1])

}

以上程序中,先将变量imgresult放入切片中,等待起的协程中,该变量值改变了,切片中的该值也会改变

 

遇到的问题3:根据向chan中存放固定值来保持线程同步

解决方法:定义个chan大小为10,向该chan中存放值,一个协程存放,一个协程取出。如果存放9个,则取出十个,则取出的协程会卡住。

测试小程序:

func test(downloadimgchan chan int32) {

fmt.Println("test func:", len(downloadimgchan))

//time.Sleep(time.Second*9)

downloadimgchan <- 1

}

func test1(receive chan int32) {

for j:=0; j<10; j++ {

<- receive

fmt.Println("111111:", len(receive))

}

}

func main() {

downloadimagechan := make(chan int32, 10)

for i:=0; i<9; i++ {

go test(downloadimagechan)

}

go test1(downloadimagechan)

time.Sleep(time.Second*90)

fmt.Println("-----------------------------------------1111111111111:", downloadimagechan)

}

 

 

转载地址:http://qnown.baihongyu.com/

你可能感兴趣的文章
爬虫手记(scrapy实现断点续爬,文章重点在设置)使用scrapy_redis
查看>>
maven 命令行打包
查看>>
Sourcetree卡顿优化
查看>>
怎么通过Excel导入sqlserver数据库(无废话)
查看>>
微信公众号开发-自定义菜单(无需代码)
查看>>
快速了解IDEA中Maven模块里各功能作用
查看>>
Navicat中update语句出现 将截断字符串或二进制数据 错误
查看>>
Elasticsearch查询、精确查询、统计数量和删除
查看>>
wangEditor上传不了图片
查看>>
PageHelper快速上手
查看>>
xml转json,以及踩过的坑
查看>>
IDEA创建application.yml文件最快捷方法
查看>>
关于“No converter found for return value of type: class” 解决的两种方式
查看>>
根据逗号或者空格进行分割字符串并进行遍历
查看>>
通过IDEA快速下载JDK
查看>>
启动elasticsearch时报错:找不到本地JDK或者JDK版本不匹配
查看>>
sqlserver “top”附近有语法错误
查看>>
@NotNull注解失效原因之一
查看>>
Gradle与Maven对比
查看>>
MYSQL和SQLSERVER创建只读账号(图解)
查看>>