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

东莞市官网网站建设平台医院网站建设 不足

东莞市官网网站建设平台,医院网站建设 不足,河南省建设厅代建中心,wordpress 手动删除插件文章目录 1 概念2 分类3 操作3.1 channel 的创建3.1.1 无缓冲channel3.1.1 带缓冲channel 3.2 channel的读写3.3 channel的关闭3.4 channel 和 select 4 channel 底层原理 1 概念 channel 是一个通道,用于端到端的数据传输,这有点像我们平常使用的消息队…

文章目录

    • 1 概念
    • 2 分类
    • 3 操作
      • 3.1 channel 的创建
        • 3.1.1 无缓冲channel
        • 3.1.1 带缓冲channel
      • 3.2 channel的读写
      • 3.3 channel的关闭
      • 3.4 channel 和 select
    • 4 channel 底层原理

1 概念

channel 是一个通道,用于端到端的数据传输,这有点像我们平常使用的消息队列,只不过 channel 的发送方和接受方是 goroutine 对象,属于内存级别的通信。

2 分类

3 操作

在深入了解 channel 的底层之前,我们先来看看 channel 的常用用法。

3.1 channel 的创建

3.1.1 无缓冲channel

 ch := make(chan int)

对于无缓冲的 channel,一旦有 goroutine 往 channel 写入数据,那么当前的 goroutine 会被阻塞住,直到有其他的 goroutine 消费了 channel 里的数据,才能继续运行写入数据。

3.1.1 带缓冲channel

还有另外一种是有缓冲的 channel,它的创建是这样的:

ch := make(chan int, 10)

其中,第二个参数表示 channel 可缓冲数据的容量。只要当前 channel 里的元素总数不大于这个可缓冲容量,则当前的 goroutine 就不会被阻塞住。

另外,我们也可以声明一个 nil 的 channel,只是创建这样的 channel 没有意义,读、写 channel 都将会被阻塞住。一般 nil channel 用在 select 上,让 select 不再从这个 channel 里读取数据,如下用法:

ch1 := make(chan int)
ch2 := make(chan int)
go func() {if !ok { // 某些原因,设置 ch1 为 nilch1 = nil}}()
for {select {case <-ch1: // 当 ch1 被设置为 nil 后,将不会到达此分支了。doSomething1()case <-ch2:doSomething2()}
}

3.2 channel的读写

3.3 channel的关闭

ch := make(chan int,10)...
close(ch)

面试题:当关闭channel之和再操作channel会发生什么?

写数据:则程序会直接 panic 退出;
读数据:(1) 有数据:读到关闭之前写入的数据;
    (2) 无数据:将得到零值,即对应类型的默认值。

3.4 channel 和 select

在写程序时,有时并不单单只会和一个 goroutine 通信,当我们要进行多 goroutine 通信时,则会使用 select 写法来管理多个 channel 的通信数据:

 ch1 := make(chan struct{})ch2 := make(chan struct{})// ch1, ch2 发送数据go sendCh1(ch1)go sendCh1(ch2)// channel 数据接受处理for {select {case <-ch1:doSomething1()case <-ch2:doSomething2()}}

channel 的死锁
前面提到过,往 channel 里读写数据时是有可能被阻塞住的,一旦被阻塞,则需要其他的 goroutine 执行对应的读写操作,才能解除阻塞状态。

然而,阻塞后一直没能发生调度行为,没有可用的 goroutine 可执行,则会一直卡在这个地方,程序就失去执行意义了。此时 Go 就会报 deadlock 错误,如下代码:

 func main() {ch := make(chan int)<-ch// 执行后将 panic:// fatal error: all goroutines are asleep - deadlock!}

因此,在使用 channel 时要注意 goroutine 的一发一取,避免 goroutine 永久阻塞!

4 channel 底层原理

前面提及过 channel 创建后返回了 hchan 结构体,现在我们来研究下这个结构体,它的主要字段如下:

type hchan struct {//channel分为无缓冲和有缓冲两种。//对于有缓冲的channel存储数据,借助的是如下循环队列的结构qcount   uint           // 循环队列中的元素数量dataqsiz uint           // 循环队列的长度buf      unsafe.Pointer // 指向底层循环队列的指针elemsize uint16         //能够收发元素的大小closed   uint32        //channel是否关闭的标志elemtype *_type        //channel中的元素类型//有缓冲channel内的缓冲数组会被作为一个“环型”来使用。//当下标超过数组容量后会回到第一个位置,所以需要有两个字段记录当前读和写的下标位置sendx    uint   // 下一次发送数据的下标位置recvx    uint   // 下一次读取数据的下标位置//当循环数组中没有数据时,收到了接收请求,那么接收数据的变量地址将会写入读等待队列//当循环数组中数据已满时,收到了发送请求,那么发送数据的变量地址将写入写等待队列recvq    waitq  // 读等待队列sendq    waitq  // 写等待队列lock mutex //互斥锁,保证读写channel时不存在并发竞争问题
}

channel 在进行读写数据时,会根据无缓冲、有缓冲设置进行对应的阻塞唤起动作,它们之间还是有区别的。下面我们来捋一下这些不同之处。

无缓冲 channel
由于对 channel 的读写先后顺序不同,处理也会有所不同,所以,还得再进一步区分:

channel 先写再读
在这里,我们暂时认为有 2 个 goroutine 在使用 channel 通信,按先写再读的顺序,则具体流程如下:

可以看到,由于 channel 是无缓冲的,所以 G1 暂时被挂在 sendq 队列里,然后 G1 调用了 gopark 休眠了起来。

接着,又有 goroutine 来 channel 读取数据了:

此时 G2 发现 sendq 等待队列里有 goroutine 存在,于是直接从 G1 copy 数据过来,并且会对 G1 设置 goready 函数,这样下次调度发生时, G1 就可以继续运行,并且会从等待队列里移除掉。

channel 先读再写
先读再写的流程跟上面一样。

G1 暂时被挂在了 recvq 队列,然后休眠起来。

G2 在写数据时,发现 recvq 队列有 goroutine 存在,于是直接将数据发送给 G1。同时设置 G1 goready 函数,等待下次调度运行。

有缓冲 channel
在分析完了无缓冲 channel 的读写后,我们继续看看有缓冲 channel 的读写。同样的,我们分为 2 种情况:

channel 先写再读
这一次会优先判断缓冲数据区域是否已满,如果未满,则将数据保存在缓冲数据区域,即环形队列里。如果已满,则和之前的流程是一样的。

当 G2 要读取数据时,会优先从缓冲数据区域去读取,并且在读取完后,会检查 sendq 队列,如果 goroutine 有等待队列,则会将它上面的 data 补充到缓冲数据区域,并且也对其设置 goready 函数。

channel 先读再写
此种情况和无缓冲的先读再写是一样流程,此处不再重复说明。

四、总结
有缓冲 channel 和无缓冲 channel 的读写基本相差不大,只是多了缓冲数据区域的判断而已。

channel 在使用的时候大多时候得和 select 配合使用,尽管只需要简单的用 <- ch 和 ch <- 来读写数据,但它的底层还是很有讲究的,特别是涉及到调度的休眠唤起。

这也能看出 Go 的精妙之处:复杂底层,优雅运用。

http://www.yayakq.cn/news/650192/

相关文章:

  • 最好网页游戏网站做爰全过程免费的视频网站有声音
  • 网站开发环境介绍网站邮件模板
  • 犀牛云建设网站十大免费观看软件下载
  • 做网站的必备软件辽宁省住房和城乡建设厅
  • 响应式网站跟自适应网站的区别获取网站访客qq号
  • 建设银行官方网站认证贵州住房城乡建设厅官方网站
  • dede重工蓝色企业免费网站模板莱芜网站建设开发公司
  • 茂名公司网站设计企业首次建设网站的策划方案
  • 哈尔滨网站建设 熊掌号wordpress 注册 填写密码错误
  • asp网站怎么验证到百度站长360网址大全电脑版
  • 网站添加百度统计代码吗平凉市城乡建设局网站
  • dedecms网站空白wordpress黑客
  • 网站建设维护外包广西城乡建设厅证件查询
  • 网站公司的客户怎么来网站域名和备案公司可以不一样么
  • 12316网站建设方案微商推广哪家好
  • 免费单页网站保险公司网站策划
  • 英文网站建设需要准备什么网站管理员登陆域名
  • 招聘网站做沙龙wordpress模板有哪些
  • 网站翻新后seo怎么做建设房屋出租网站
  • 网站的内链建设垂直电商平台有哪些
  • 石家庄网站推广软件济宁做网站的公司
  • 中学加强校园网站建设高端科技产品网站建设
  • 城乡与建设部网站首页wordpress 表格提交
  • 食品网站网页设计七牛云存储 wordpress插件
  • 空间网站打不开泰州住房和城乡建设网站
  • 个人 做自媒体 建网站企业邮箱注册哪个好
  • 2018网站建设合同如何收集网站建设资料
  • 网站空间文件夹1920的做网站做多大
  • 网站建设方案图自助建站系统哪个最好用
  • 简述网站建设主要流程vps网站打开速度调节