go并发编程之channel

news2024/9/24 9:26:37

目录

1.简介

2.channel类型

无缓冲区的channel

无缓冲区channel的创建

带缓冲区的channel

 带缓冲区channel的创建

3.channel使用代码演示

 4.获取channel中的值

​编辑

5.单向channel

单向发送data,发送到channel中

单向接收,channel接收数据

6.channel使用中的死锁


1.简介

channel通道是一种比较重要的数据结构,用于多个协程之间的通信。

可以把channel想象成一个传送带,将协程想象成传送带周边的人,一个人往传送带上放东西,传送带另一端的人将传送带的东西取走。

也就是左边的goroutine是负责发送数据的,右边的goroutine是负责接收数据的。data会通过channel,从左边的goroutine传送的右边的goroutine。

2.channel类型

 channel类型分为两种类型,一种是无缓冲的channel,一种是有缓冲的channel。

无缓冲区的channel

对于无缓冲区的channel来说,channel本身是不存储数据的,整个channel的发送和接收都会被阻塞。

如下图,左边协程发送数据到右边协程,当data还没有被右边的协程接收处理完的时候,左边的协程会被阻塞发送数据,左边的协程发送的data会被阻塞到外面,只有当右边的协程获取数据之后,左边的协程才能继续将数据发送出去。

无缓冲区channel的创建

①先声明再实例化

var c chan interface{}
c = make(chan interface{})

②直接实例化

c := make(chan interface{})

带缓冲区的channel

带缓冲区的channel会有暂存数据的功能,当channel缓冲区满了或者空(空的话可以理解为是不带缓冲区的channel)的时候,channel的发送和接收会被阻塞。

如下图:

channel为空的话,相当于是无缓冲区的channel。

假设定义一个缓冲区大小为3的channel,向里面发送三个data,当达到缓冲区的大小的时候,发送端的协程的数据会被阻塞,直到接收端的协程接收玩一个data数据,发送端的协程才可以发送下一个数据。

 带缓冲区channel的创建

与无缓冲区channel不同的是,带缓冲区的channel需要指定缓冲区大小。

①先声明,后初始化,创建一个缓冲区大小为2的channel

var c chan interface{}
c = make(chan interface{},2)

②直接创建

c := make(chan interface{},2)

3.channel使用代码演示

func main() {
    // 定义一个无缓冲的channel
	ch := make(chan int)
    
    // 开启一个协程,往里面添加1
	go func() {
		ch <- 1
	}()
    
    // 主协程获取channel里面的data
	v := <-ch
	fmt.Printf("v is %d",v)
}

那么无缓冲的协程阻塞怎么做到的呢?

首先创建一个无缓冲的通道 ,发送端发送一个,接收端接收一个值。

go协程和主协程是并发运行的,使用go关键字开启一个协程是需要时间初始化的,所以先执行的是

func main() {
	ch := make(chan string)
	s := []string{"A","B","C","D"}

	// 协程的创建需要一些时间
	go func() {
		// 执行玩,关闭chan,要不然主线程会一直从chan中获取空数据,导致panic
		defer close(ch)
		for _, v := range s {
			fmt.Printf("send to chan %v\n",v)
			ch <- v
			// 每间隔1秒往chan中发送一条数据
			time.Sleep(1 * time.Second)
		}
	}()
	fmt.Println("5秒开始")
	time.Sleep(5*time.Second)
	fmt.Println("5秒结束")
	
	// 获取chan中的数据
	for val := range ch {
		fmt.Printf("received %v\n",val)
	}
}

执行的结果:

首先执行主线程,5s开始,间隔5s,此时go线程初始化好,执行go协程中的内容,发送数据到通道,每间隔1s往chan中发送一条数据。此时主协程接收chan中的数据。

 那么有缓冲区的通道呢?

定义一个大小为2的有缓冲区的通道,当无缓冲区的时候,可以传送一个,加上缓冲区的大小

func main() {
	ch := make(chan string,2)
	s := []string{"A","B","C","D"}
	go func() {
		defer close(ch)
		for _, v := range s {
			fmt.Printf("send to chan %v\n",v)
			ch <- v
			// 每间隔1s发送一个数据
			time.Sleep(1*time.Second)
		}
	}()
	fmt.Println("5s开始")
	time.Sleep(5*time.Second)
	fmt.Println("5s结束")
	for c := range ch {
		fmt.Printf("received %v\n",c)
	}


}

 4.获取channel中的值

方式一:
<-ch

方式二:
for range
func main() {
	ch := make(chan int)
	go func() {
  // 		defer close(ch)  // 此时ok是false
      ch <-1

	}()

    // 获取管道中的值,一个是从管道中获取发送方发送的值,另一个是go中默认的一个值
    // ok的意思是成功从管道中获取值,ok就是true,否则就为false

	v, ok := <-ch
	fmt.Printf("%v is %v\n",v,ok)
}

5.单向channel

发送还是接收,具体看通道变量c 后面的变量

单向发送data,发送到channel中

var c chan<- interface{}
c = make(chan<- interface{})

c := make(chan<- interface{})

单向接收,channel接收数据

var c <-chan interface{}
c = make(<- chan interface{})
c := make(<- chan interface{})

6.channel使用中的死锁

对于一个已经阻塞的channel来说,如果继续发送或者接收,会出现死锁运行中的错误。

非缓冲区的只有发送或者接收,会出现阻塞,产生死锁

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

汇编的各种指令及使用方法

***************************************************************** 汇编中的符号 1.指令&#xff1a; 能够编译生成一条32位的机器码&#xff0c;且能被CPU识别和执行 2.伪指令&#xff1a;本身不是指令&#xff0c;编译器可以将其替换成若干条等效指令 3.伪操作&#xff1a…

Linux进程间通信——管道(下)

前文 一&#xff0c;什么是命名管道? 二&#xff0c;命名管道的基本原理 三&#xff0c;创建命名管道实现两个进程对写 四&#xff0c;匿名管道和命名管道的区别 总结 前文 上篇文章我们主要讲了匿名管道的定义以及基本原理&#xff0c;但是匿名管道有一个致命的缺陷&#…

HashSet、LinkedHashSet、TreeSet有什么区别

- HashSet、LinkedHashSet 和 TreeSet 都是 Set接口的实现类&#xff0c;都能保证元素唯一&#xff0c;并且都不是线程安全的。HashSet 的底层数据结构是哈希表&#xff08;基于 HashMap 实现&#xff09;&#xff0c;元素存入和取出顺序不一致。LinkedHashSet 的底层数据结构…

C++制作五子棋

正文 01 思路 我没有选择专业的五子棋棋型&#xff0c;用我自己的逻辑&#xff08;初高中玩五子棋的方法&#xff09;&#xff0c;去实现简单的人机对战。 首先因为要计算五子棋每一步的分数&#xff0c;那么你就要分析每一步形成的棋盘&#xff0c;以下图为例&#xff1a;…

蓝桥杯专题-试题版含答案-【风险度量】【括号配对问题】【ASCII码排序】【素数求和】

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 &#x1f449;关于作者 专注于Android/Unity和各种游…

【Java高级编程】枚举类注解

枚举类&注解 1、枚举类的使用1.1、枚举类的使用1.2、如何定义枚举类1.3、Enum类的主要方法 2、注解的使用2.1、注解的概述2.2、常见的Annotation示例2.3、如何自定义注解&#xff1a;参照SuppressWarnings定义2.4、JDK提供的4种元注解2.5、JDK 8中注解的新特性&#xff1a;…

2023-06-25:redis中什么是缓存穿透?该如何解决?

2023-06-25&#xff1a;redis中什么是缓存穿透&#xff1f;该如何解决&#xff1f; 答案2023-06-25&#xff1a; 缓存穿透 缓存穿透指的是查询一个根本不存在的数据&#xff0c;在这种情况下&#xff0c;无论是缓存层还是存储层都无法命中。因此&#xff0c;每次请求都需要访…

关于C++图论树的某些题图形提示

一、去教室的路。 猫猫大学有n条路&#xff0c;每条路都有一个数字编号&#xff0c;其中的一条路一定与另外2条路相连&#xff0c;请你打出这个学校的地图。 输入1&#xff1a; 1 2 3 4 2 3 45 4 45 1 输出1&#xff1a; 1 2 3 4 5 45 图解 &#xff1…

动态住宅代理VS静态住宅代理,怎么选择?

现在&#xff0c;越来越多的海外代理服务商均支持动态住宅IP与静态住宅IP,很多小伙伴就疑惑&#xff0c;这二者有什么区别呢&#xff1f;哪个更好&#xff1f;其实&#xff0c;没有哪个更好&#xff0c;只有哪一个更合适您的业务。 无论动态住宅IP还是静态住宅IP都来自真实的住…

【软件测试】10道性能测试高频面试题,你能答上多少?

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、性能测试包含了…

表格el-table多出一条横线,怎么解决(el-table表格下方多一条线的问题)

最近在写el-table表格的时候&#xff0c;发现的问题&#xff0c;表格多出一条横线&#xff0c; 可以看出其它行&#xff0c;都是正常显示&#xff0c;只有第7行多出一条横线&#xff0c;找了好久&#xff0c; 最后发现是el-table表格的伪元素&#xff0c;问题就出在这&#xf…

B站化播放量为播放时长,是谁的狂欢?

6月26日晚&#xff0c;B站举办了14周年庆典晚会。在晚会上&#xff0c;除了周深、美依礼芽同框献唱受到关注&#xff0c;B站董事长兼CEO陈睿的演讲内容同样值得深思&#xff1a; 一来&#xff0c;陈睿提到&#xff0c;要将目前B站视频前台显示的播放量数据从次数改为分钟数&am…

精进ARM计算架构,催生人工智能产业的巨大跨越

在优化ARM计算架构以支持人工智能应用方面&#xff0c;以下是一些常见的方法和技术&#xff1a; 算法和模型设计优化&#xff1a;选择合适的算法和模型结构对于在ARM架构上高效执行人工智能任务至关重要。设计轻量级的模型、减少冗余操作和参数量&#xff0c;使用适合ARM架构的…

【K8S系列】深入解析K8S调度

序言 做一件事并不难&#xff0c;难的是在于坚持。坚持一下也不难&#xff0c;难的是坚持到底。 文章标记颜色说明&#xff1a; 黄色&#xff1a;重要标题红色&#xff1a;用来标记结论绿色&#xff1a;用来标记论点蓝色&#xff1a;用来标记论点 Kubernetes (k8s) 是一个容器编…

扩展ExtendedFloatingActionButton滚动收缩展开行为

效果 首先ExtendedFloatingActionButton有默认的Behavior : ExtendedFloatingActionButtonBehavior,这个类是为了ExtendedFloatingActionButton不被SnakBar所遮挡&#xff0c;并且这个类它是protected,所以为了保留原有的设计&#xff0c;自定义的Behavior不能在外部定义&#…

Go语言单元测试

1、Go语言单元测试 Go语言中的测试依赖 go test 命令&#xff0c;go test 命令是一个按照一定约定和组织的测试代码的驱动程序。在包目录 内&#xff0c;所有以 _test.go 为后缀名的源代码文件都是 go test 测试的一部分&#xff0c;不会被 go build 编译到最终的可执行 文件…

【Python爬虫】利用爬虫抓取双色球开奖号码,获取完整数据,简洁45行代码实现,更新时间2023-06-28

链接&#xff1a;https://pan.baidu.com/s/18oE308_NVNPaCOACw_H5Hw?pwdabc1 利用爬虫抓取双色球开奖号码&#xff0c;获取完整数据&#xff0c;简洁45行代码实现&#xff0c;更新时间2023-06-28 这是网上的数据&#xff0c;怎么将它爬取下来 它将只爬取最近30期的双色球开…

星辰秘典:解开Python项目的神秘面纱——迷宫之星(迷宫探索与求解)

✨博主&#xff1a;命运之光 &#x1f338;专栏&#xff1a;Python星辰秘典 &#x1f433;专栏&#xff1a;web开发&#xff08;html css js&#xff09; ❤️专栏&#xff1a;Java经典程序设计 ☀️博主的其他文章&#xff1a;点击进入博主的主页 前言&#xff1a;你好&#x…

文件系统理解——磁盘文件

磁盘文件 1. 问题提出2. 了解磁盘的物理结构2.1 磁盘大体结构2.2 磁盘的具体物理结构 3.对磁盘结构逻辑抽象3.1 OS是通过CSH方法进行扇区的管理的吗&#xff1f;3.2 磁盘逻辑过程 4.文件系统4.1 管理思想4.2 区结构Boot BlockSuper BlockGroup Descriptor Tableinode Table &am…

共享办公室在国内外的发展史以及现状介绍

共享办公室&#xff0c;这个曾经陌生的概念&#xff0c;如今已成为全球范围内炙手可热的话题。在这个时代&#xff0c;越来越多的人开始关注灵活性和协作性&#xff0c;而共享办公室正是在这种需求下应运而生的。本文将带您一探共享办公室的国内外发展史、国内当前发展现状以及…