首页 > 其他分享 >Go笔记(十四):通道 channel

Go笔记(十四):通道 channel

时间:2023-05-06 09:03:52浏览次数:31  
标签:ch01 缓冲 make chan 笔记 time Go channel 通道

1、通道

  通道channel是Go提供的一种用于各个协程(goroutine)之间的数据共享,保证数据同步交换的机制。协程是轻量级线程,类似于Java中的线程。

2、通道的类型

2.1、无缓冲通道

  用于同步通信,可保证在发送和接收数据时完成两个goroutine(协程)的数据交换。

2.2、缓冲通道

  用于异步通信,可接收到一个或多个值之前保存它们。通道中没有接收的值时,接收会阻塞;通道中没有可用的缓存区存放正在发送的值时,发送会阻塞。

3、通道的声明

声明通道是需指定数据类型,数据在通道上传递,任何给定时间只有一个goroutine可访问数据项,因此不会发生数据竞争。

通道由make函数创建,需指定chan关键字和通道的元素类型。

·创建无缓冲通道

// 字符串无缓冲通道
make(chan string) 

·创建有缓冲通道

// 字符串有缓冲通道
make(chan string, 10) 

  使用内置函数make创建无缓冲和缓冲通道,make的第一个参数需要关键字chan,然后是通道允许交换的数据类型。

代码示例如下:

 1 package main
 2 
 3 import (
 4     "fmt"
 5     "math/rand"
 6     "time"
 7 )
 8 
 9 // 创建string类型通道,只能传入int类型值
10 var vc = make(chan int)
11 
12 func send() {
13     // 生成随机数
14     rand.Seed(time.Now().UnixNano())
15     value := rand.Intn(10)
16     fmt.Printf("send: %v\n", value)
17     // 睡眠1s
18     time.Sleep(time.Second)
19     // 将数据写入通道
20     vc <- value
21 }
22 
23 func main() {
24     // 关闭通道
25     defer close(vc)
26     // 创建一个协程执行send
27     go send()
28     fmt.Println("wait...")
29     // 将通道的值写入value变量中
30     value := <-vc
31     fmt.Println("value : ", value)
32     fmt.Println("send...")
33 }

执行结果如下:

 

4、通道接收及发送数据

1、通道接收数据

ch := make(chan string, 3)  // 字符串缓冲通道
ch <- "hello" // 将数据写入通道

2、通道发送数据

data := <-通道变量名

示例代码如下:

 1 package main
 2 
 3 import (
 4     "fmt"
 5     "time"
 6 )
 7 
 8 // 创建通道
 9 var ch01 = make(chan string, 5)
10 
11 func main() {
12 
13     // 关闭通道
14     defer close(ch01)
15 
16     go func() {
17         str := "hello"
18         fmt.Printf("send: %v\n", str)
19         time.Sleep(time.Second)
20         ch01 <- str
21     }()
22 
23     fmt.Println("wait...")
24     // 将通道的值写入value变量中
25     value := <-ch01
26     fmt.Println("value : ", value)
27     fmt.Println("over...")
28 
29 }

执行结果如下:

  

5、通道的遍历

  用for range遍历通道获取数据,若通道关闭,读多写少,没有了就是默认值;若没有关闭,会造成死锁。

 1 package main
 2 
 3 import "fmt"
 4 
 5 func main() {
 6     // 通道未关闭,读多写少,没有了就是默认值
 7     ch01 := make(chan int)
 8     go func() {
 9         // 关闭通道
10         defer close(ch01)
11         // 写数据进入通道
12         for i := 0; i < 2; i++ {
13             ch01 <- i
14         }
15     }()
16     for i := 0; i < 5; i++ {
17         data := <-ch01
18         fmt.Printf("ch01 data: %v\n", data)
19     }
20     fmt.Println("----------------------")
21     // for rang遍历
22     ch02 := make(chan int)
23     go func() {
24         // 关闭通道
25         defer close(ch02)
26         // 写数据进入通道
27         for i := 0; i < 10; i++ {
28             ch02 <- i
29         }
30     }()
31     for v := range ch02 {
32         fmt.Printf("ch02 date: %v\n", v)
33     }
34 }

  执行结果如下:

  

6、通道的发送和接收特性

  1、对于同一个通道,发送操作之间是互斥的,接收操作也是互斥的;

  2、发送和接收操作是原子的;

  3、发送操作在完全完成之前会被阻塞。接收操作也是如此。

 

标签:ch01,缓冲,make,chan,笔记,time,Go,channel,通道
From: https://www.cnblogs.com/RunningSnails/p/17375878.html

相关文章

  • Go笔记(十五):并发编程
    一、协程的创建Go语言支持并发,只需要通过go关键字来开启goroutine(协程)即可。goroutine(协程)是轻量级线程,goroutine(协程)的调度是由Golang运行时进行管理的。goroutine语法格式(创建协程):go函数名(参数列表)示例代码如下:1packagemain2imp......
  • go测试库之apitest
    前言使用go语言做开发差不多快一年了,主要用来写后端Web服务,从一开始吐槽他的结构体,比如创建个复杂的JSON格式数据,那是相当的痛苦。还有err处理写的巨麻烦。当然,go也有爽的地方,创建个线协程简直太简单了。到后来慢慢接受,觉得效率还行,因为是静态强类型语言,在修改完项目代码之......
  • 常用的截取字符串方法JS和Golang实现
    JS中截取字符串很简单,直接使用substr函数substr()方法可在字符串中截取从开始下标开始的指定数目的字符。下标是从0开始算例如:"21".substr(0,1)  返回2golang实现的substr//截取字符串,支持多字节字符//start:起始下标,负数从从尾部开始,最后一个为-1//length:截取长度,......
  • golang控制语句和运算符
    一、go程序基础1、文件名go语言文件名命名规范:go语言的文件名必须以.go结尾。go语言的文件名必须以小写字母开头,否则会报错。go语言的文件名不能包含空格,否则会报错。go语言的文件名不能包含特殊字符,否则会报错。go语言的文件名不能包含中文,否则会报错。go语言的文件名不......
  • 5.5笔记
    1、格式化输入输出   CPU、内存、I/O设备在快速发展的过程中,有一个核心矛盾一直存在,就是三者之间的速度差异   平衡三者之间鸿沟的有效手段就是引入缓存   键盘---->stdin(内存,行缓冲区,标准输入缓冲区)---->程序---->stdout(内存,行缓冲区,标准输出缓冲区)---->屏幕 ......
  • go 快速入门
    1.下载并安装gin:$goget-ugithub.com/gin-gonic/gin使用Gomodules工具管理项目初始化gomod$gomodinitlearninggopackagemainimport"github.com/gin-gonic/gin"funcmain(){r:=gin.Default()r.GET("/ping",func(c*gin.Context......
  • 云原生时代崛起的编程语言Go常用标准库实战
    @目录基础标准库简述字符串-string底层结构函数长度格式化输出模版-templatetext/templatehtml/template正则表达式-regexp编码-encodingBase64JSONXML时间-time网络-netURLHTTP客户端和服务端加密IO操作读写文件环境变量命令行数据库排序-sort测试和基准测试基础标准库简述Go......
  • mongodb使用and配合or查询
    使用mongodb时,有时需要使用and配合(嵌套)or查询。实现类似以下sql的语句:select*fromMongoDbTestwherestatus=1and(userId="abc"orprice>=2)对应的mongodb语句如下:db.getCollection("mongoDbTest").find({"status":1,"$and":[{"$or&q......
  • SpringBoot配置mongodb打印日志
    在application.yml添加配置:logging:level:org.springframework.data.mongodb.core.MongoTemplate:DEBUG如果使用的是application.properties,则是:logging.level.org.springframework.data.mongodb.core.MongoTemplate=DEBUG......
  • Velocity----学习笔记
    Velocity判断空值方法:依据:$username与$!username的区别,当找不到username的时候,$username返回字符串"$username",而$!username返回空字符串""所以:#set($!username=='')可以判断字符串是否为空 以下为Velocity脚本摘要1、声明:#set($var=XXX)左边可以是以下的内容Variablereferen......