文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

golang chan用法

2023-05-16 14:53

关注

Golang是一种强类型语言,以其高并发性和简洁的语法而闻名。其中,chan是Golang中常见的通信方式之一,也是实现并发编程的重要组成部分。在本文中,我们将深入了解Golang中chan的用法和基本原理。

一、chan的概念和作用

chan是Golang中实现goroutine间通信的重要方式,简称管道。它是一种线程安全的数据结构,用于在Golang程序中传递信息。chan可以实现单向通信和双向通信,可以用于发送和接收数据,也可以用于同步goroutine。

二、chan的类型和使用方式

Golang中的chan是一个类型,可以使用make函数来创建。语法如下:

ch := make(chan int)

其中int表示管道里传递数据的类型。使用chan时需要注意以下几点:

  1. chan是阻塞式的

发送和接收操作都是阻塞式的,即如果没有发送和接收操作匹配,那么goroutine会一直阻塞在这个操作上。例如:

ch := make(chan int)

// 发送操作
go func() {
   ch <- 1
}()

// 接收操作
a := <- ch

在这个例子中,我们创建了一个int类型的管道,分别进行了发送和接收操作。在发送操作中,我们向管道中发送了一个值1;在接收操作中,我们从管道中取出了值并赋值给了变量a。由于发送和接收操作都是阻塞式的,所以这个程序会一直等待直到发送和接收操作匹配,才能正常结束。

  1. 关闭chan

可以使用close函数来关闭管道,关闭后的管道不能再次进行发送操作。例如:

ch := make(chan int)

// 发送操作
go func() {
   ch <- 1
   close(ch)
}()

// 循环接收操作
for {
   if val, ok := <-ch; ok {
      fmt.Println(val)
   } else {
      break
   }
}

在这个例子中,我们在发送操作之后调用了close函数,然后使用for循环对管道进行接收操作。接收操作中,使用了ok来判断管道是否已经关闭,防止出现死锁现象。

  1. 单向chan

通过设置管道的方向,可以创建单向chan。例如:

ch := make(chan int) // 双向chan

// 定义只能发送的单向chan
sendCh := make(chan <- int)

// 定义只能接收的单向chan
recvCh := make(<- chan int)

// 发送操作时可以使用单向chan
go func() {
   sendCh <- 1
}()

// 接收操作时也可以使用单向chan
a := <-recvCh

在这个例子中,我们通过make函数创建了一个双向chan,然后通过make函数分别创建了只能发送和只能接收的单向chan。在发送操作和接收操作中,我们分别使用了sendCh和recvCh。

  1. select语句

select语句可以同时监听多个管道的状态,可以用于管道的并发读取和写入操作。例如:

ch1 := make(chan int)
ch2 := make(chan int)

// 发送操作
go func() {
   ch1 <- 1
}()

// 使用select语句并发监听多个管道
select {
case a := <- ch1:
   fmt.Println(a)
case b := <- ch2:
   fmt.Println(b)
}

在这个例子中,我们创建了两个管道ch1和ch2,并在一个goroutine中向ch1中发送了值1。此后,我们使用select语句监听了两个管道,优先执行收到第一个值的case语句。

三、chan的基本原理

在Golang中,chan是基于特殊的数据结构实现的。当我们使用make函数创建chan时,实际上创建了一个值为nil、长度为0的切片,称之为channel。

我们可以通过以下方式来理解chan的原理:

  1. 发送操作

在进行发送操作时,会将待发送的数据附加到channel底层的切片中。如果channel的长度为0,那么添加的元素的下标为0。如果channel的长度不为0,那么添加的元素的下标为channel的长度。

如果channel的长度已经达到了其容量上限,那么会在内存中新建一个更大的切片,并将原来的切片中的元素拷贝到新的切片中。因此,在进行发送操作时,会使用到内存管理和拷贝的机制。

  1. 接收操作

在进行接收操作时,会从channel底层的切片中取出最先被附加进去的元素。如果切片中没有元素,那么会一直等待,直到有元素可取;如果channel已经被关闭,那么接收操作会立即返回一个零值。

  1. 阻塞

当进行发送或接收操作时,如果channel的切片长度已经达到其容量上限,或者channel中已有数据等待被接收,那么发送或接收操作会一直处于阻塞状态,直到有足够的空间或数据可用。

  1. 关闭操作

在关闭channel时,会将channel的状态设置为已关闭,并不能再进行发送数据。如果channel中有未被接收的数据,那么可以继续进行接收操作,直到channel中没有数据为止。

总结

Golang中的chan是一种实现goroutine间通信的重要方式,从语法上看也非常简洁。掌握chan的基本用法和原理对于并发编程是非常重要的。

以上就是golang chan用法的详细内容,更多请关注编程网其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯