当前位置: 首页 > news >正文

网站建设与管理维护说课免费空间申请free

网站建设与管理维护说课,免费空间申请free,有什么网站可以做深圳初二的试卷练习,做网站注意哪些Golang中的channel为什么要使用channelchannel的介绍channel的基本使用定义/声明channel管道的遍历和关闭channel的关闭channel的遍历goroutine和channel结合应用实例1应用实例2案例注意事项为什么要使用channel 前面使用全局变量加锁同步来解决goroutine的通讯,但…

Golang中的channel

    • 为什么要使用channel
    • channel的介绍
    • channel的基本使用
      • 定义/声明channel
    • 管道的遍历和关闭
      • channel的关闭
      • channel的遍历
    • goroutine和channel结合
      • 应用实例1
      • 应用实例2
      • 案例
    • 注意事项

为什么要使用channel

前面使用全局变量加锁同步来解决goroutine的通讯,但不完美

  • 1.主线程在等待所有goroutine全部完成时间很难确定,我们这里设置10秒,仅仅是过段
  • 2.如果主线程休眠时间长了,会加长等待时间,如果等待时间短了,可能还有routine处于工作状态,这时也会随主线程的退出而销毁
  • 3.通过全局白能量加锁同步来实现通讯,也并不利用多个协程对全局变量的读写操作
  • 4.上面种种分析都在互换一个新的通讯机制-----channel

channel的介绍

  • 1.channel本质就是一个数据结构-队列
  • 2.数据是先进先出
  • 3.线程安全,多goroutine访问时,不需要加锁,就是说channel本身就是线程安全的
  • 4.channel是有类型的,一个string的channel只能存放string类型数据
    在这里插入图片描述

channel的基本使用

定义/声明channel

var 变量名chan数据类型

举例:

var intChan chan int (intChan用于存放int数据)

var mapChan chan map[int]ssting (mapChan用于存放map[int]string类型)

var perChan chan Person

var perChan2 chan *Person

说明:

channel是引用类型

channel必须初始化才能写入数据,即make后才能使用

管道是有类型的,intChan只能写入整数

package mainimport "fmt"func main() {//演示一下管道的使用//创建一个可以存放三个int类型的俄管道var intChan chan intintChan = make(chan int, 3)//看看intChan是什么fmt.Printf("intChan的值=%v intChan本身的地址=%p\n", intChan, &intChan)//向管道写入数据intChan <- 10num := 211intChan <- num//看看管道的长度和cap(容量)fmt.Printf("channel len = %v cap=%v \n", len(intChan), cap(intChan))//从管道中读取数据var num2 intnum2 = <-intChanfmt.Println("num2=", num2)fmt.Printf("channel len =%v cap=%v \n", len(intChan), cap(intChan))//在没有使用协程的情况下,如果我们管道数据已经全部取出,在取就会报告deadlock
}
/*
intChan的值=0xc00010e080 intChan本身的地址=0xc000006028
channel len = 2 cap=3 
num2= 10              
channel len =1 cap=3  
*/

管道的遍历和关闭

channel的关闭

使用内置函数close可以关闭channel,当channel关闭后,就不能再想channel写数据了,但是仍然可以从给channel读取数据

channel的遍历

channel支持for-range的方式进行遍历

1.在遍历时,如果channel没有关闭,则会出现deadlock的错误

2.在遍历时,如果channel已经关闭,则会出现正常遍历数据,遍历完后,就会退出遍历

package mainimport "fmt"func main() {intChan := make(chan int, 3)intChan <- 100intChan <- 200close(intChan)//这时不能够再写入到channel//intChan <- 300fmt.Println("okk")n1 := <-intChanfmt.Println("n1=", n1)//遍历管道intChan2 := make(chan int, 100)for i := 0; i < 100; i++ {intChan2 <- i * 2 //放入100个数据到管道}// 在遍历时,如果channel没有关闭,责护出现deadlock的错误close(intChan2)for v := range intChan2 {fmt.Println("v=", v)}}

goroutine和channel结合

应用实例1

在这里插入图片描述

在这里插入图片描述

package mainimport ("fmt""time"
)func writeData(intChan chan int) {for i := 1; i < 50; i++ {//放入数据intChan <- ifmt.Println("writeData", i)time.Sleep(time.Second)}close(intChan) //关闭
}//read data
func readData(intChan chan int, exitChan chan bool) {for {v, ok := <-intChanif !ok {break}time.Sleep(time.Second)fmt.Printf("readData读到数据=%v\n", v)}//readData读取完数据后,即任务完成exitChan <- trueclose(exitChan)
}func main() {//创建两个管道intChan := make(chan int, 50)exitChan := make(chan bool, 1)go writeData(intChan)go readData(intChan, exitChan)//time.Sleep(time.Second * 10)for {_, ok := <-exitChanif !ok {break}}
}

应用实例2

如果只是向管道写入数据,而没有读取,就会出现阻塞而dead lock,原因是intChan容量是10,而带点吗writeData会写入50个数据,因此就会阻塞在writeData的ch<-i

案例

在这里插入图片描述

package mainimport "fmt"func putNum(intChan chan int) {for i := 1; i <= 8000; i++ {intChan <- i}//关闭intChanclose(intChan)
}//开启四个协程,从intChan取出数据,并判断是否为素数
//如果是,就放入到primeChan
func primeNum(intChan chan int, primeChan chan int, exitChan chan bool) {//使用for循环var flag boolfor {num, ok := <-intChanif !ok {break}flag = true //假定是素数//判断num是不是素数for i := 2; i < num; i++ {if num%i == 0 { //说明该num不是素数flag = falsebreak}}if flag {//将这个数就放入到primeChanprimeChan <- num}}fmt.Println("有一个primeNum协程因为取不到数据,退出")//这里还不能关闭primeChan//向exitChan写入trueexitChan <- true
}func main() {intChan := make(chan int, 1000)primeChan := make(chan int, 2000) //放入结果//标识退出的管道exitChan := make(chan bool, 4)//开启一个协程,想in特产放入1-8000个数go putNum(intChan)//开启四个协程,从intChan取出数据,并判断是否为素数//如果是,就放入到primeChanfor i := 0; i < 4; i++ {go primeNum(intChan, primeChan, exitChan)}//这里进行主线程处理go func() {for i := 0; i < 4; i++ {<-exitChan}//当我们从exitChan,去出了4个结果,就可以放心关闭primeChanclose(primeChan)}()//遍历primeNum,把结果输出for {res, ok := <-primeChanif !ok {break}//将结果输出fmt.Printf("素数=%d\n", res)}fmt.Println("main线程退出")
}

注意事项

  • 1.channel可以声明为只读,或者只写性质
  • 2.channel只读和只写的最佳实践案例
package mainimport "fmt"func main() {//管道可以声明为只读或者只写//默认情况下,管道是双向的//var chan1 chan int//声明为只写var chan2 chan<- intchan2 = make(chan int, 3)chan2 <- 20//num := <-chan2fmt.Println("chan2=", chan2)//声明为只读var chan3 <-chan intnum2 := <-chan3fmt.Println("num2=", num2)
}
  • 3.使用select可以解决从管道取数据的阻塞问题
  • 4.goroutine中使用recover,解决携程中出现panic,导致程序奔溃问题
    • 说明,如果我们起了一个协程,但是这个协程出现了panic,如果我们没有捕获这个panic,就会造成整个程序崩溃,这是我们可以在goroutine中使用recover来捕获panic,进行处理,这样及时这个协程发生的问题,但是主线程仍然不受影响,
http://www.yayakq.cn/news/232484/

相关文章:

  • 江西赣鄂皖路桥投资有限公司网站建设开发网站建设的问卷调查
  • ipv6网站建设东莞梅州建站电话
  • 莆田网站制作方案定制开发网站开票写什么
  • 企业网站新闻如何建设西安的商城网站
  • 聊城网站优化技术济宁贵网站建设
  • 网站后台框架下载上海网页设计公司
  • 制作网制作网站建设的公司西安seo顾问培训
  • wordpress手机网站怎么做wordpress 全局广告
  • 怎么网站建设网站建设注册密码咋弄
  • 南京网络科技网站建设哪个免费建站好
  • 做受免费网站怎么样建立自己的网站
  • google chrome谷歌浏览器seo综合诊断工具
  • 成都建站提供商网站的开发建设费
  • 东阳网站建设yw12605网课时作业本
  • 建筑公司网站背景图有赞微商城官网登入
  • 富锦网站西斗门的网站建设
  • 罗湖网站-建设深圳信科WordPress网站远程访问
  • 获取网站js网站投入费用
  • 美食网站开发的难点人人车网站建设费用
  • 企石镇做网站足球教学网站
  • 合肥专业建站机械设计网
  • 网站建设编辑教程企业网页设计素材
  • 广州联雅做的网站怎么样珠宝网站设计方案
  • 河北唐山建设工程协会网站PHP做的网站能容纳多少人
  • 免费的公文写作网站外贸网站优化在线推广
  • 陕西建设厅证件查询网站电脑培训班多少费用
  • 简单网站建设视频教程株洲最新通告
  • 网站地址栏图标怎么做永久免费建站程序
  • 福田商城网站建设建站快车
  • 用什么手机软件做网站微擎小程序