二十五、go语言的通道

news/2024/9/18 20:41:36/ 标签: golang, 开发语言, 后端

目录

一、收发通信

二、将通道作为参数传递(读、写、读写)

三、select

1、先收到消息的先执行

2、一直没有收到消息退出通道

3、不知道何时退出情况下退出通道


go语言中的goroutine可以看成线程,但是又不能看成和其它语言一样的线程,因为在go语言中,goroutine之间的通信和其它语言不一样,例如如果在java中多条线程访问一个内存中数据在访问前需要进行加锁避免其它线程进入进行修改,本质上是通过共享了内存进行通信。而在go中是不一样的,在go中是“不要通过共享内存进行通信,而是通过通信来共享内存”

一、收发通信

import ("fmt""time"
)func receiver(c chan string) {for msg := range c {fmt.Println(msg)}
}
func main() {message := make(chan string, 2)message <- "hello"message <- "world"close(message)fmt.Println("push two message to channel")time.Sleep(time.Second * 2)receiver(message)
}

结果在2s中后输出

hello
world
解释

上述案例中 receiver函数接收了一个通道为string值的参数,并且进行循环输出

main方法中,mak(chan string,2)声明创建长度为2的通道

message <- "" 往通道内存入消息

close关闭通道意味着不可以再通过这个通道发送消息

调用receiver并传入message参数

二、将通道作为参数传递(读、写、读写)

在参数中<-在chan左边意味着可读,在右边意味着可写,没有意味着可读可写

func showReader(c <-chan string) {msg := <-cfmt.Println(msg)
}
func showWriter(c chan<- string) {c <- "hello world"
}func showReaderAndWriter(c chan string) {msg := <-cfmt.Println(msg)c <- "hello world"
}

在reader函数中,c是什么我们只能输出什么

在writer函数中,c是什么我们可以修改

在readerAndWriter函数中,c是什么我们可以输出什么也可以指定c是什么

三、select

1、先收到消息的先执行
func ping(c chan int) {time.Sleep(time.Second * 3)c <- 1
}
func ping2(c chan<- int) {time.Sleep(time.Second * 2)c <- 2
}
func main() {channel := make(chan int)channel2 := make(chan int)go ping(channel)go ping2(channel2)select {case msg := <-channel:fmt.Println(msg)case msg := <-channel2:fmt.Println(msg)}
}

结果:

2

解释L

在select中最先收到消息的执行后续代码,当创建两个ping方法时,ping sleep了3秒,ping2 sleep了2秒所以先执行了ping2

2、一直没有收到消息退出通道

当一直没有收到消息可以使用case <-time.After(time.Second * 3):

import ("fmt""time"
)func ping(c chan int) {time.Sleep(time.Second * 5)c <- 1
}
func ping2(c chan<- int) {time.Sleep(time.Second * 4)c <- 2
}
func main() {channel := make(chan int)channel2 := make(chan int)go ping(channel)go ping2(channel2)select {case msg := <-channel:fmt.Println(msg)case msg := <-channel2:fmt.Println(msg)case <-time.After(time.Second * 3):fmt.Println("timeout")}}
3、不知道何时退出情况下退出通道
import ("fmt""time"
)func sender(c chan string) {t := time.NewTicker(1 * time.Second)for {c <- "hello world"<-t.C}
}
func main() {messages := make(chan string)stop := make(chan bool)go sender(messages)go func() {time.Sleep(2 * time.Second)fmt.Println("time up")stop <- true}()for {select {case status := <-stop:fmt.Println(status)returncase msg := <-messages:fmt.Println(msg)}}
}

结果:

hello world
hello world
hello world
time up
true


解释:

 创建了一个sender方法,使用time.NewTicker(1 * time.Second),每一秒往通道中传递一次值

t := time.NewTicker(1 * time.Second)
for {c <- "hello world"<-t.C
}

在for循环中执行 

case msg := <-messages:fmt.Println(msg)

在接收到消息后执行,那么如果在没有手动终止程序的话就会一直执行

所以创建一个退出通道,当接收到true值时进行return,退出通道

case status := <-stop:fmt.Println(status)return

在同时并发执行一个func,并让这个程序sleep 2秒后,在给通道stop值为true

go func() {time.Sleep(2 * time.Second)fmt.Println("time up")stop <- true}()

所以在第一次并发调用

go sender(messages)

执行了一次

fmt.Println(msg)

此时func开始sleep 2秒,所以又执行了两次,当stop为ture时进行了return退出了通道


http://www.ppmy.cn/news/1519819.html

相关文章

【Kubernetes知识点问答题】Namespace(命名空间)

目录 1. 什么是 K8s 的 namespace&#xff1f; 2. 系统默认创建了哪几个 namespace&#xff1f; 1. 什么是 K8s 的 namespace&#xff1f; 在 K8s 中&#xff0c; Namespace&#xff08;命名空间&#xff09;提供了一种机制&#xff0c;将同一集群中的资源划分为相互隔离的组…

c# net8调用vc写的dll

dll程序&#xff08;vc,x86) 头文件 extern "C" int __declspec(dllexport) WINAPI add(int a, int b);实现 int WINAPI add(int a, int b) {return a b; }c#/net8 函数声明&#xff1a; [DllImport("dll/Dll1.dll", CallingConvention CallingCo…

Git 提交代码注释信息规范

在团队协作开发过程中&#xff0c;规范的 Git 提交信息不仅能提高代码维护的效率&#xff0c;还能让其他开发者更容易理解每次提交的目的和内容。下面是常用的 Git 提交信息类型及其详细说明。此外&#xff0c;还包括一些额外的提交类型&#xff0c;以便更全面地覆盖开发过程中…

线程池相关知识点

线程池是什么相信大家都是知道的&#xff0c;所以这里就不做解释了&#xff0c;直接看相关知识点吧。 初始化线程池方法 继承ThreadPool 实现Runnable 实现Callable 接口 FutureTask &#xff08;可以拿到返回结果&#xff0c;可以处理异常&#xff09; 核心参数 corePoo…

将string类中能够实现的操作都封装在MyString类中

包括&#xff1a; 构造函数 析构函数 重载 &#xff0c;[]&#xff0c;,,,!,<,>,<,>,<<,>>; at&#xff1b; data&#xff1b; c_str; empty; length; capasityacity; clear; push_back; pop_back; append; 程序中我封装了大部分&#…

el-time-select 动态增加时间

<template><div><div v-for"(item, index) in timeSlots" :key"index"><el-time-select placeholder"起始时间" v-model"item.startTime" :picker-options"{start: 00:00,step: 00:15,end: 23:59,}"&g…

语音控制开关的语音识别ic芯片方案

语音控制开关是一种基于语音识别技术的设备&#xff0c;它通过内置的语音识别芯片&#xff0c;将用户的语音指令转化为电信号&#xff0c;从而实现对设备的控制。例如在智能家居设备上的应用&#xff0c;通常需要连接到家庭的Wi-Fi网络上&#xff0c;以便与智能手机或智能音箱等…

用实时计算释放当下企业大数据潜能

摘要&#xff1a;本文整理自阿里云高级产品解决方案架构师王启华&#xff08;敖北&#xff09;老师在 Flink Forward Asia 2023 中闭门会的分享。内容分为以下四个部分&#xff1a; 业务需求变化推动架构演进实时计算对于企业生产的意义从技术架构和技术场景来看发展和迭代客户…

使用 streamlink 把 m3u8 转为 mp4

问题描述&#xff0c; 背景&#xff0c; 来源&#xff1a; 下载 m3u8 ts —> 转为mp4, 按照以往的做法&#xff0c; 就是使用 python requests 一步一步地下载 m3u8, ts&#xff0c; 然后转换。 但是个人写的东西&#xff0c;毕竟问题比较多。 而且&#xff0c; 但是&…

2024 年的 Web3 游戏:演变、趋势和市场动态

Web3 游戏行业在经历了多年的快速发展和变革之后&#xff0c;正在2024年迎来全新的阶段。这个行业从最初的边玩边赚&#xff08;Play-to-Earn, P2E&#xff09;模式出发&#xff0c;如今正在向更为平衡的“边玩边赚”模式转型。这种转型不仅解决了早期 P2E 模式下存在的可持续性…

MyBatis-SQL-语句执行流程

已查询为例 首先我们可以看到&#xff0c;在查询的时候Mapper对象已经是被代理过后的&#xff1a; 所以会执行invoke方法&#xff0c;其底层实现就是JDK的动态代理&#xff1a; 如下图所示&#xff0c;如果MethodCache里面存在方法&#xff0c;则判断这个方法是否为default方…

python实现人工神经网络

要编写一个简单的人工神经网络&#xff08;ANN&#xff09;程序&#xff0c;可以从一个基本的前馈神经网络开始&#xff0c;该网络通常包括输入层、一个或多个隐藏层以及输出层。在这个例子中&#xff0c;将使用Python的NumPy库来处理数学运算&#xff0c;并使用Sigmoid函数作为…

【Python批量下载Landsat数据】

批量下载Landsat数据&#xff08;例如Landsat 8 OLI/TIRS&#xff09;可以通过多种方法实现&#xff0c;但通常涉及使用在线服务或API接口&#xff0c;如USGS EarthExplorer、Google Earth Engine&#xff08;GEE&#xff09;或者专门的库如landsatxplore&#xff08;一个Pytho…

配置了680M和780M集显的AMD CPU列表

AMD Radeon 680M 核显配置在以下型号的 CPU 上面&#xff1a; - Ryzen 9 6980HX&#xff1a;8 核心 16 线程&#xff0c;最高加速时钟频率可达 5.0GHz&#xff0c;配备 12CU RDNA 2 架构的 Radeon 680M 核显&#xff0c;频率为 2.4GHz 。 - Ryzen 9 6900HX&#xff1a;8 核心 …

MAC环境导出项目的目录结构

一、安装Homebrew包管理工具 /bin/bash -c "$(curl -fsSL https://gitee.com/ineo6/homebrew-install/raw/master/install.sh)" 官网网址&#xff1a;https://brew.idayer.com/ 二、用brew包管理工具安装tree brew install tree 三、打开终端&#xff0c;导出项目…

深入Redis:细谈持久化

Redis的数据是保存在内存中的&#xff0c;内存里面的数据是不持久的&#xff0c;要想做到持久化&#xff0c;必须要把在内存中的数据储存到硬盘上。 Redis速度非常快&#xff0c;数据只有在内存中才有这样的速度&#xff0c;但是为了持久&#xff0c;数据还是要想办法保存到硬…

Java Excel转PDF(免费)

目前市面上 Excel 转 PDF 的组件较多&#xff1a; 收费&#xff1a;aspose、GcExcel、spire开源&#xff1a;jacob、itextpdf 其中收费的组件封装得比较好&#xff0c;代码简洁&#xff0c;转换的效果也很好&#xff0c;但收费也高得离谱&#xff1a; 为了成本考虑&#xff…

videojs宫格视频选择播放

项目需要四宫格播放视频&#xff0c;而且还要实现点击视频加入播放。 首先&#xff0c;肯定要实现再一个页面上显示多个视频源并播放视频&#xff1a; <template><div><div v-for"(item,index) in videoList" :key"index" class"te…

在ElementUI项目中集成iconfont图标库

在前端项目开发中经常会遇到使用的组件库提供的ICON图标不够用的情况。最常见的解决方案无非就是把设计图的图标切图引入到项目中。还有就是使用svg图标&#xff0c;封装一个渲染组件在项目里面直接引入这个组件。 本文将介绍另一种方法&#xff0c;即集成iconfont图标库的图标…

9、LLaMA-Factory项目微调介绍

1、LLaMA Factory 介绍 LLaMA Factory是一个在GitHub上开源的项目&#xff0c;该项目给自身的定位是&#xff1a;提供一个易于使用的大语言模型&#xff08;LLM&#xff09;微调框架&#xff0c;支持LLaMA、Baichuan、Qwen、ChatGLM等架构的大模型。更细致的看&#xff0c;该项…