17.Golang channel的基本定义及使用

目录

  • 概述
  • 实践
    • 无缓冲 channel
      • 代码
      • 结果
    • 缓冲 channel
      • 代码
      • 结果
    • channel的关闭特点
      • 代码
      • 结果
      • range代码
      • 结果
    • select channel
      • 代码
      • 结果
  • 结束

概述

此篇文章介绍 channel 的用法

  • 无缓冲 channel
  • 缓冲 channel
  • channel的关闭特点
  • range channel
  • select channel

每一种,配上完整的代码及相应的测试结果,对关键的部分,配置上图及对应说明。

实践

无缓冲 channel

未分配空间的 channel 具有 阻塞的功能。交互的 goroutine 两都都会阻塞的效果。

无缓充的 channel
在这里插入图片描述
总结如下:

  • 第1步,两个 goroutine 都到达通道,但都没有开始执行发送或接收
  • 第2步,左侧的 goroutine 将手伸进了通道,模拟了向通道发送数据的行为。此时,这个 goroutine 会在通道中被锁住,直道交换完成。
  • 第3步,右侧 goroutine 将手放入通道,模拟了从通道里接收数据。这个 goroutine 一样也会在通道中被锁住,直到交换完成
  • 第4步与第5步,进行交换。并最终,在第6步,两个 goroutine 都将手从通道里拿出来,模拟了被锁住的 goroutine 得到释放。

代码

package main

import "fmt"

func main() {
	// 定义一个 channel,并没有分配空间
	c := make(chan int)

	// 匿名函数
	go func() {
		defer fmt.Println("goroutine调用结束...")
		fmt.Println("goroutine 正在运行...")
		c <- 666
	}()

	num := <-c
	fmt.Println("num:=", num)
	fmt.Println("main goroutine 结束。。。")

}

结果

执行结果如下:
在这里插入图片描述

缓冲 channel

在这里插入图片描述

  • 第1步,右侧的 goroutine 正在从通道接收一个值
  • 第2步,右侧的这个 goroutine 独立 完成了 接收值 的动作,而左侧的 goroutine 正在发送一个新值至通道里
  • 第3步,左侧的 goroutine 还在向通道发送新值,而右侧的 goroutine 正在从通道接收另外一个值。这两个步骤里的操作既不是同步的,也不会相互阻塞。
  • 第4步,所有的发送和接收都完成,而通道里还有几个值,也有一些空间可以存更多的值。

特点:当 channel 已经满,再向里面写数据,就会阻塞,当 channel 为空时,从里面取数据也会阻塞。

代码

package main

import (
	"fmt"
	"time"
)

func main() {

	// 带有缓冲的 channel
	c := make(chan int, 3)
	fmt.Println("len(c)= ", len(c), " ,cap(c)=", cap(c))

	go func() {
		defer fmt.Println("子goroutine执行结束...")

		for i := 0; i < 4; i++ {
			c <- i
			fmt.Println("子goroutine正在运行,发送的元素=", i, "len(c)= ", len(c), " ,cap(c)=", cap(c))
		}
	}()

	time.Sleep(2 * time.Second)

	for i := 0; i < 4; i++ {
		num := <-c
		fmt.Println("num=", num)
	}

	fmt.Println("main 结束...")
}

结果

执行结果如下:
在这里插入图片描述

channel的关闭特点

  • channel 不像文件一样需要经常关闭,只有确实没有任何发送数据了,或者想显式的结束 range 循环之类的,才去关闭 channel
  • 关闭 channel 后,无法向 channel 再发送数据(引发 panic 错误后导致接收立即返回零值)
  • 关闭 channel 后,可以继续从 channel 接收数据
  • 对于 nil channel ,无论收发都会被阻塞

代码

package main

import "fmt"

func main() {
	c := make(chan int)
	go func() {
		for i := 0; i < 5; i++ {
			c <- i
		}
		// close可以关闭一个 channel
		close(c)
	}()

	for {
		// ok 如果为true表示channel没有关闭,如果为false表示channel已经关闭
		if data, ok := <-c; ok {
			fmt.Println(data)
		} else {
			break
		}
	}

	fmt.Println("main finished...")
}

结果

执行结果如下:
在这里插入图片描述

range代码

range 写法,完整代码如下

package main

import "fmt"

func main() {
	c := make(chan int)
	go func() {
		for i := 0; i < 5; i++ {
			c <- i
		}
		// close可以关闭一个 channel
		close(c)
	}()

	// 可以使用 range 来迭代不断操作 channel
	for data := range c {
		fmt.Println(data)
	}
}

结果

range-channel 测试结果如下
在这里插入图片描述

select channel

代码

package main

import "fmt"

func main() {
	c := make(chan int)
	quit := make(chan int)
	go func() {
		for i := 0; i < 5; i++ {
			fmt.Println(<-c)
		}
		// close可以关闭一个 channel
		quit <- 0
	}()

	x, y := 1, 1
	for {
		select {
		case c <- x:
			// 如果 c 可写,则该 case 会进来
			x = y
			y = x + y
		case <-quit:
			fmt.Println("quit")
			return
		}
	}

}

结果

在这里插入图片描述

结束

Golang channel的 基本定义及使用 至此结束,如有疑问,欢迎评论区留言。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/361696.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深入浅出AI落地应用分析:AI个人助手Monica

前言:铺天盖地的大模型以及所谓的应用到目前为止实际还是很少有像Monica这样贴合个人工作习惯的产品落地,比如像Chatgpt等这样的产品,绝大多数人不会专门买🪜翻墙出去用,而且大多数场景下素人或小白都不知道该怎么用,但是Monica这款产品就很好的以浏览器的插件的形式始终…

29 python快速上手

Python操作MySQL和实战 1. 事务1.1 MySQL客户端1.2 Python代码 2. 锁2.1 排它锁2.2 共享锁 3. 数据库连接池4. SQL工具类4.1 单例和方法4.2 上下文管理 5.其他总结 目标&#xff1a;掌握事务和锁以及Python操作MySQL的各种开发必备知识。 概要&#xff1a; 事务锁数据库连接池…

【Oracle云】使用 boto3 访问 OCI 对象存储 (AWS S3协议兼容)

在现代云计算环境中&#xff0c;S3&#xff08;Simple Storage Service&#xff09;协议已经成为云对象存储的事实标准。它提供了简单、可扩展、高度耐用的存储解决方案&#xff0c;得到了广泛应用。Oracle Cloud Infrastructure&#xff08;OCI&#xff09;秉承着开放性和灵活…

摄像头监控系统/视频监控云平台EasyCVR接入单兵设备后如何配置移动规矩

视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。音视频流媒体视频平台EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体控可实现视频监控直播、视频轮播、视频录像…

Java编程练习之类的封装

1.把一个Student类封装起来&#xff0c;模拟一个转校生转入新学校后为其制作学生信息的过程。运行结果如下&#xff1a; package zhtestdemo; import java.util.Scanner; import java.text.DecimalFormat; public class demo { //创建类&#xff0c;类名叫demo; private Stud…

CentOS7中安装ElasticSearch

文章目录 检测是否安装了Elasticsearch安装JDK下载java配置 下载Elasticsearch解压安装Elasticsearch修改配置文件启动Elasticsearch常见问题 ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎&#xff0c;基于RESTful web接口。Elasti…

【Ubuntu 18.04 安装截图软件 flameshot 】

安装命令&#xff1a; sudo apt-get install flameshot 使用命令&#xff1a; flameshot gui 创建快捷键&#xff1a;设备->键盘->>输入名字和快捷键 截完图后保存CtrlS&#xff0c;复制到剪贴板 CtrlC ​​​​​​

Altium Designer的学习

PCB设计流程 1.新建空白工程&#xff1a; 创建一个新的工程 新建四个文件&#xff0c;并且保存&#xff1a; 每次打开文件时&#xff0c;打开以.PrjPcb结尾的文件 2.元件符号的创建&#xff1a; 在绘制图形的时候设置成10mil,为了在原理图中显得不那么大。 在绘制引脚的时候设…

【软考问题】-- 6 - 知识精讲 - 项目成本管理

一、基本问题 项目成本管理&#xff08;预算内完成&#xff09; 1&#xff1a;成本管理计划 定义&#xff1a;是项目管理计划的组成部分&#xff0c; 描述将如何规划、 安排和控制项目成本。在计划中一般要规定 计量单位精确度&#xff1a;例如 995.59 元取整为 1000元准确度&…

【Qt】—— Qt Creator界⾯认识

目录 &#xff08;一&#xff09;左边栏 &#xff08;二&#xff09;代码编辑区 &#xff08;三&#xff09;UI设计界⾯ &#xff08;四&#xff09;构建区 &#xff08;一&#xff09;左边栏 在编辑模式下&#xff0c;左边竖排的两个窗⼝叫做"边栏"。 ①是项⽬…

【TCP】三次握手(建立连接)

前言 在网络通信的世界里&#xff0c;可靠传输协议&#xff08;TCP&#xff09;扮演着重要的角色&#xff0c;它保证了数据包能够按顺序、完整地从发送端传送到接收端。TCP协议中有一个至关重要的机制——三次握手。这一过程确保了两个TCP设备在开始数据传输之前建立起一个稳定…

数字孪生产品评测:五款数字孪生产品的优劣对比

作为数据可视化领域的资深用户&#xff0c;我深知数字孪生产品在当今工业4.0时代的重要地位。本文将为大家介绍五款市面上的数字孪生产品&#xff0c;帮助大家了解各产品之间的优缺点&#xff0c;选择适合自己的产品。 一、山海鲸可视化 山海鲸可视化是一款强大而灵活的免费数…

C++(map和set)

目录 前言 正文 1.预备知识 1.1序列式容器 1.2关联式容器 1.3键值对 2.set 2.1概念 ​编辑 2.2set的使用 2.3set总结 2.4multiset 3.map 3.1概念 3.2、map的使用 3.3map中operator[] 3.4map总结 3.5multimap 前言 s et 和 map 是 STL 中的容器之一&a…

matlab自定义函数实现图像小波变换

matlab中提供了小波变换函数lwt和ilwt&#xff0c;可以方便地实现提升小波变换。 我们按照小波变换的定义&#xff0c;粗糙地实现一个针对图像的小波变换&#xff0c;如下&#xff1a; % 使用方法&#xff1a; img imread(lena256.bmp); % 假设lena.png是灰度图像 subplot(2…

单细胞转录组数据分析的10大软件/流程

单细胞数据分析现在已经有上千个软件工具可供使用了&#xff0c;这为用户带来便利的同时也造成了选择困难。就像时间一样&#xff0c;一个表&#xff0c;没问题&#xff0c;但如果有两个表&#xff0c;时间还不一样&#xff0c;该信谁的呢&#xff1f; 正好我们前面一篇文章介绍…

Windows10更新失败 错误 0x80070643、KB5034441的解决方法之二

Windows10更新失败 错误 0x80070643、KB5034441 在知乎Windows10更新失败 错误 0x80070643、KB5034441的原因分析和几个解决方法 - 知乎 参考文章进行操作&#xff0c;更详细信息自己看上面链接。 我电脑的硬盘是mbr格式&#xff0c;而且没有划分恢复分区。 Microsoft Windo…

JS(react)图片压缩+图片上传

上传dome var fileNodeTakeStock: any createRef();<inputref{fileNodeTakeStock}onChange{showPictureTakeStock}style{{ display: "none" }}id"fileInpBtn"type"file"accept"image/*" //限制上传格式multiple{false}capture&qu…

C++继承与多态

一&#xff0c;继承 1&#xff0c;继承定义 继承是C三大特性之一。C有类型的复用&#xff1a;类型模板&#xff0c;函数的复用&#xff1a;函数重载。而继承其本质是一种类的复用&#xff0c;使得程序员可以在原有类特性之上进行扩展来产生新的类&#xff0c;原有的类称为父类…

【深度学习】全连接神经网络

全连接神经网络 全连接神经网络的结构 整体结构 神经网络:类似神经元,前一层可以不断地传递给下一层。 神经网络模型由多个单元结构组成。 单元结构 单元结构的数学公式: a = h ( w x + b ) a=h(wx+b) a=h(wx+b) h(x):激活函数 比如sigmoid就是激活函数之一隐藏层大多…

Collections集合工具类-JAVA

java.util.Collections:是个集合工具类它不是集合&#xff0c;而是集合的工具类 常用 API&#xff1a;注意 binarySearch 方法要求元素有序 方法实现&#xff1a; public class Test01 {public static void main(String[] args) {ArrayList<String>list1new ArrayList…