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

什么网站可以找人做系统郑州做网站哪家好

什么网站可以找人做系统,郑州做网站哪家好,怎么自己创建一个网站,深圳整站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.hkea.cn/news/627540/

相关文章:

  • 漳州网站设计东莞网站制作模板
  • 制作应用的软件成都排名seo公司
  • 北京专业企业网站建设俄罗斯搜索引擎入口 yandex
  • wordpress 怎么改中文网站推广优化价格
  • 南山做网站公司怎么选择企业seo优化服务
  • 什么 电子商务网站建设与管百度招商加盟
  • 南召微网站开发手机优化大师官方版
  • 营销型网站技术特点网站推广网
  • 龙游县住房和城乡建设局网站百度seo优化方法
  • 深圳方维网站建设设计个人网站
  • wordpress 流量站百度应用
  • ps素材网seo在线工具
  • 岳阳网站开发公司html网站模板免费
  • 怎样用模板做网站优化网站技术
  • 全国新型疫情最新情况长沙网站搭建优化
  • 郑州网站建设规划seo建站教程
  • 购物网站 购物车界面如何做百度搜索网
  • 推广网站的图片怎么做外贸平台
  • 新手如何给自己的网站做优化bt种子磁力搜索
  • 成都学校网站制作遵义网站seo
  • d?t网站模版宁波seo在线优化哪家好
  • c做的网站淄博做网站的公司
  • 网站开发制作公司郑州网站建设外包
  • 注册域名用个人还是公司好长沙seo优化排名
  • 电子商务网站建设与维护展望今日新闻联播
  • 网站建设主流技术站长之家ping检测
  • 温州建设集团有限公司网站首页百度手机版网页
  • 广西网络干部学院官网seo推广人员
  • 可以做红娘的相亲网站江北seo综合优化外包
  • 公司建设网站需要注意什么软文广告示范