当前位置: 首页 > news >正文

go基础知识归纳总结

无缓冲的 channel 和有缓冲的 channel 的区别?

在 Go 语言中,channel 是用来在 goroutines 之间传递数据的主要机制。它们有两种类型:无缓冲的 channel 和有缓冲的 channel。

  1. 无缓冲的 channel

行为:无缓冲的 channel 是一种同步的通信方式,发送和接收必须同时发生。如果一个 goroutine 试图通过无缓冲 channel 发送数据,它会阻塞,直到另一个 goroutine 从该 channel 中接收数据。反之亦然,接收方在准备好接收数据之前,发送方无法继续执行。
用法:适合在两个 goroutines 之间实现精确的同步,确保它们在同一时刻传递数据。
优点:
保证了发送和接收的同步,可以避免某些类型的并发错误。
更简单,适合需要严格按顺序处理任务的场景。
缺点:
性能上可能存在瓶颈,因为必须等待对应的发送或接收操作才能继续执行。

无缓冲的 Channel 示例

package mainimport ("fmt""time"
)func main() {// 创建一个无缓冲的 channelch := make(chan int)// 启动一个 goroutine 来接收数据go func() {// 接收数据之前会阻塞,直到 main goroutine 发送数据val := <-chfmt.Println("接收到的数据:", val)}()// 模拟一些操作time.Sleep(1 * time.Second)// 发送数据到 channel,会阻塞直到接收方读取数据ch <- 42fmt.Println("数据已发送")
}

由于是无缓冲的 channel,main goroutine 在发送 42 时会阻塞,直到 goroutine 从 channel 中接收到这个值,程序才会继续执行。
2. 有缓冲的 channel

行为:有缓冲的 channel 容许在 channel 中存储一定数量的数据元素,发送方可以在 channel 未满时继续发送数据,而无需等待接收方。接收方只有当 channel 非空时才会接收数据。
用法:适合发送方和接收方的处理速度不一致的情况,允许发送方先发送一部分数据,接收方稍后接收。
优点:
提供了一定的并发灵活性,发送方可以在接收方未准备好时先发送一定数量的数据。
提高了性能,减少了因为同步阻塞而导致的性能损耗。
缺点:
如果缓冲区设计不当,可能会出现缓冲区溢出或浪费资源的情况。
由于有缓冲的存在,可能会导致发送和接收之间的时间不同步,增加调试和排查问题的难度。
总结
无缓冲的 channel 强调的是同步性,适合需要严格同步的场景。

有缓冲的 channel 提供更多的灵活性,允许在并发处理中有更大的自由度,不需要完全同步。
在使用中,可以根据具体场景选择合适的 channel 类型。例如,在生产者-消费者模型中,有缓冲的 channel 可以防止生产者等待消费者处理;而在需要精确同步的任务中,无缓冲 channel 则更加合适。

有缓冲的 Channel 示例

package mainimport ("fmt""time"
)func main() {// 创建一个带有缓冲区大小为 2 的 channelch := make(chan int, 2)// 发送两个数据到 channelch <- 1fmt.Println("发送了数据 1")ch <- 2fmt.Println("发送了数据 2")// 此时,由于缓冲区还有空间,发送不会阻塞go func() {// 延迟读取,模拟一些操作time.Sleep(2 * time.Second)val := <-chfmt.Println("接收到的数据:", val)}()// 继续发送数据time.Sleep(1 * time.Second)ch <- 3fmt.Println("发送了数据 3")// 接收数据time.Sleep(2 * time.Second)val := <-chfmt.Println("接收到的数据:", val)
}

这里的 channel 有缓冲区大小为 2,因此前两个 ch <- 操作不会阻塞,因为缓冲区有足够空间。第三次发送数据时,如果缓冲区已满,发送方会阻塞,直到接收方读取数据并释放空间。

channel和select底层数据结构是怎样的?

Go 中 select 语句的底层实现涉及多个关键数据结构和调度机制,主要是为了高效地处理通道(channel)操作和 Goroutine 调度。我们可以从 Go 语言的源代码中窥探其底层数据结构。以下是 select 相关的几个重要底层数据结构和其如何与通道和 Goroutine 协同工作:

  1. Goroutine 和 P 结构
    Go 的并发模型基于 Goroutine 和 M
    调度模型。每个 select 语句本质上都会涉及到 Goroutine 的阻塞与唤醒。调度器的核心数据结构包括:
    Goroutine(G):代表一个执行中的协程,每个 Goroutine 都包含了当前执行状态、栈信息等。当某个 select 语句阻塞 Goroutine 时,Goroutine 会被挂起,并与通道关联。
    P(Processor):代表一个运行 Goroutine 的处理器,它与 OS 线程(M)配合使用,管理并调度多个 Goroutine。
    当某个 select 语句涉及到通道的操作时,如果通道未就绪,当前 Goroutine 会被放入通道的等待队列中,并挂起,直到被调度器唤醒。
  1. 通道(Channel)结构
    通道的底层结构非常重要,因为 select 语句的核心在于处理通道操作。通道的内部结构如下
type hchan struct {qcount   uint           // 通道中已经存在的数据个数dataqsiz uint           // 环形队列的大小buf      unsafe.Pointer // 环形队列的指针elemsize uint16         // 每个元素的大小closed   uint32         // 通道是否关闭sendx    uint           // 发送操作的索引recvx    uint           // 接收操作的索引recvq    waitq          // 等待接收的 Goroutine 队列sendq    waitq          // 等待发送的 Goroutine 队列
}

recvq/sendq:表示接收和发送操作等待的 Goroutine 队列。当 select 语句中有对通道的接收或发送操作时,如果通道未就绪,当前 Goroutine 会被加入相应的等待队列。

  1. SelectCase 结构
    Go 运行时使用一个名为 SelectCase 的数据结构来表示 select 语句中的每个 case,每个 SelectCase 代表一个通道操作。该结构体中记录了每个 case 中的通道、操作类型(发送或接收)以及相关的数据指针等。
type scase struct {c    *hchan         // 指向通道的指针kind uint16         // 操作类型(发送、接收)pc   uintptr        // 程序计数器,用于跟踪执行位置elem unsafe.Pointer // 数据元素的指针,用于发送或接收操作
}

c:指向通道的指针,表示这个 case 监听哪个通道。
kind:表示操作类型,是发送、接收还是默认 case。
elem:存储数据的指针,用于发送或接收操作时的存取。

  1. Select 语句的执行流程
    当 Goroutine 执行一个 select 语句时,Go 运行时会执行以下操作:
    初始化 scase 列表:首先,select 语句会初始化每个通道操作,生成一个 scase 列表来表示所有的 case。
    检测是否有就绪通道:然后,运行时会遍历这些 scase,检测是否有通道已经就绪(比如是否有数据可接收,或者通道是否可以发送数据)。如果有通道就绪,立刻执行相应的操作,并返回。
    阻塞等待:如果所有通道都未就绪,当前 Goroutine 会挂起并加入到每个通道的等待队列中。此时,通道内部的 recvq 或 sendq 队列会保存当前 Goroutine 的相关信息,当通道状态发生变化时,这些队列会被唤醒,调度器会重新调度等待的 Goroutine 。
    随机选择通道:当有多个通道同时就绪时,Go 运行时通过随机函数来选择一个通道执行,保证公平性。
  2. 调度器与 select
    Go 调度器通过一组全局的队列和局部队列来管理 Goroutine 的运行状态。在 select 语句中,阻塞的 Goroutine 会被挂起到通道的等待队列中,但它们仍然保留在全局或局部队列中。当通道状态发生变化(如通道中有数据),调度器会从队列中唤醒相关的 Goroutine 并将其重新加入执行队列。
  3. select 的公平性和随机性
    Go 在 select 中实现了对多个通道操作的随机选择机制,避免某些通道操作被长期饿死。具体来说,当有多个通道同时就绪时,Go 会打乱 scase 列表的顺序,并随机选择一个通道进行处理。这确保了 select 的公平性,即使多个 Goroutine 同时监听同一组通道,也不会导致某个通道长期得不到处理。

select 的核心数据结构总结
Goroutine (G):Goroutine 是 select 语句中的执行单元,当一个 select 阻塞时,当前 Goroutine 会挂起。
hchan:通道是核心数据结构,负责管理发送和接收操作,recvq 和 sendq 队列保存了等待通道操作的 Goroutine。
scase:select 语句中每个通道操作的表示,存储了通道的指针、操作类型等信息。
调度器:Go 调度器负责管理 Goroutine 的执行和状态,当 select 语句涉及到阻塞操作时,调度器会将 Goroutine 挂起并重新调度。
通过这些底层机制,Go 的 select 语句能够高效地在并发场景下处理多个通道操作,并且在多个通道就绪时提供随机选择的公平性保障。

相关文章:

go基础知识归纳总结

无缓冲的 channel 和有缓冲的 channel 的区别&#xff1f; 在 Go 语言中&#xff0c;channel 是用来在 goroutines 之间传递数据的主要机制。它们有两种类型&#xff1a;无缓冲的 channel 和有缓冲的 channel。 无缓冲的 channel 行为&#xff1a;无缓冲的 channel 是一种同步…...

【字幕】恋上数据结构与算法之014动态数组02接口设计

申请表数组英文单词叫away&#xff0c;而这个数组是怎么样的申请表&#xff1f;数组是一种顺序存储的申请表&#xff0c;什么叫顺序存储&#xff1f;就是数组里面的所有元素&#xff0c;它的内存地址是连续的&#xff0c;大家的内存是连续的&#xff0c;比如说举个例子&#xf…...

ffmpeg硬件解码一般流程

流程 根据硬件名称&#xff0c;查询是否是支持的类型 const char *device_name "qsv"; //cuda enum AVHWDeviceType type av_hwdevice_find_type_by_name(device_name); if(type AV_HWDEVICE_TYPE_NONE) {//如果一个硬件类型是不支持的&#xff0c;打印所有支持…...

微信支付开发-程序开发

一、操作流程图 二、后端代码实现 1、题库实现 a、列表、所有、详情、保存、启禁用、导入答题 b、获取奖品信息、保存奖品信息、 class Question extends Base {// 列表public function getList(){$param $this->request->param();$where [];if(!empty($param[title])…...

【数据结构】排序算法系列——堆排序(附源码+图解)

堆排序 堆排序基于一种常见的**[[二叉树]]结构**&#xff1a;堆 我们前面讲到选择排序&#xff0c;它在待排序的n个记录中选择一个最小的记录需要比较n一1次。本来这也可以理解&#xff0c;查找第一个数据需要比较这么多次是正常的&#xff0c;否则无法知道它是最小的记录。 …...

Linux——应用层自定义协议与序列化

目录 一应用层 1再谈 "协议" 2序列化与反序列化 3理解read,write,recv,send 4Udp vs Tcp 二网络版本计算器 三手写序列和反序列化 四进程间关系与守护进程 1进程组 1.1什么是进程组 1.2组长进程 2会话 2.1什么是会话 2.2会话下的前后台进程 3作业控…...

CGAL 从DSM到DTM-建筑物区域提取

CGAL 从DSM到DTM-建筑物区域提取 生成的DSM被用作DTM计算的基础&#xff0c;即地面表示为过滤掉非地面点后的另一个TIN。主要是去除一些建筑物和植被非地形点。 建筑物立面及连通区域提取 建筑物立面的特征是三角形面片的高度变化剧烈。 通过遍历每一个三角面片&#xff0c;…...

Python--编码解码报错

报错问题 错误信息 UnicodeDecodeError: gbk codec cant decode byte 0xac in position 2: illegal multibyte sequence 通常出现在尝试使用 GBK 编码解码某些二进制数据时&#xff0c;但数据中包含了无法被 GBK 解码的字符。具体错误提示是解码器在处理某个字节时发现该字节无…...

大屏可视化常用图标效果表达

1-echarts-雷达图 2-echarts-仪表盘 3-echarts-水球图&#xff08;利用插件&#xff0c;echarts-liquidfill&#xff09; 4-element UI tree 添加连接线&#xff0c;修改样式或使用插件&#xff08;element-tree-line&#xff09; 5-echarts-漏斗图 6-echarts-饼状图嵌套 optio…...

高通Liunx 系统镜像编译

本文将会介绍如何在编译高通Liunx代码, 具体可以在高通 Linux | 高通下查看相关信息。 编译服务器配置 首先&#xff0c;准备一台Ubuntu 22.04版本主机或者服务器 1&#xff0c;编译Yocto 系统&#xff0c;需要如下一些配置 sudo apt update sudo apt install repo gawk wg…...

105、解析Java中1000个常用类:StringTokenizer类,你学会了吗?

在线工具站 推荐一个程序员在线工具站:程序员常用工具(http://cxytools.com),有时间戳、JSON格式化、文本对比、HASH生成、UUID生成等常用工具,效率加倍嘎嘎好用。程序员资料站 推荐一个程序员编程资料站:程序员的成长之路(http://cxyroad.com),收录了一些列的技术教程…...

虚幻引擎 | 实时语音转口型 Multilingual lipsync

实时语音转口型&#xff1a;EPIC的metahuman sdk&#xff0c;NVIDIA的audio2face&#xff0c;都好。本文使用metahuman sdk 需要工具&#xff1a;Metahuman SDK网页账号&#xff0c;获取两日免费tokens https://space.metahumansdk.io/#/unauthorized ———————————…...

vue国际化

前言 现在的大公司都走国际化路线&#xff0c;我们应用程序也不例外。今天就在 Vue3 项目中整一个比较简单的国际化 背景 之前搞国际化的时候&#xff0c;也搜索了很多帖子&#xff0c;但是没有一个可以完整的实现。今天有空搞了一版&#xff0c;大家有什么问题欢迎留言探讨…...

解决tiktoken库调用get_encoding时SSL超时

文章目录 解决tiktoken库调用get_encoding时SSL超时1. 获取词表文件url2. 手动下载词表文件并保存到本地3. 复制并重命名文件4. 环境变量中设置tiktoken cache5. 使用tiktoken库参考资料 解决tiktoken库调用get_encoding时SSL超时 最近在看Build a Large Language Model (From…...

C++从入门到起飞之——继承上篇 全方位剖析!

&#x1f308;个人主页&#xff1a;秋风起&#xff0c;再归来~&#x1f525;系列专栏&#xff1a;C从入门到起飞 &#x1f516;克心守己&#xff0c;律己则安 目录 1、继承的概念 2、继承定义 2.1 定义格式 2.2 继承基类成员访问⽅式的变化 3、继承类模板 4、 基…...

【文件包含】——日志文件注入

改变的确很难&#xff0c;但结果值得冒险 本文主要根据做题内容的总结&#xff0c;如有错误之处&#xff0c;还请各位师傅指正 一.伪协议的失效 当我们做到关于文件包含的题目时&#xff0c;常用思路其实就是使用伪协议&#xff08;php:filter,data,inpput等等&#xff09;执行…...

UE5源码Windows编译、运行

官方文档 Welcome To Unreal Engine 5 Early Access Learn what to expect from the UE5 Early Access program. 链接如下&#xff1a;https://docs.unrealengine.com/5.0/en-US/Welcome/#gettingue5earlyaccessfromgithub Step 0&#xff1a;找到UE5源码 直接先上链接 https…...

AI大模型与产品经理:替代与合作的深度剖析

在创业的征途中&#xff0c;产品经理常常被外界以一种半开玩笑的口吻提及&#xff1a;“就差一个程序员了。”这句话背后&#xff0c;既蕴含着对产品经理创意与策略能力的认可&#xff0c;也揭示了技术实现环节对于产品成功不可或缺的重要性。然而&#xff0c;随着AI技术的飞速…...

资本的运作方式、贷款的评估标准、杠杆率

在资本领域&#xff0c;涉及到多个角色和复杂的运作机制。以下是一些主要的角色及其运作方式&#xff1a; 主要角色 政府&#xff1a; 发行债券&#xff1a;政府通过发行国债和其他债券来筹集资金&#xff0c;用于公共支出和基础设施建设。货币政策&#xff1a;政府通过调节利…...

Python:抓取 Bilibili(B站)评论、弹幕、字幕等

个人学习需求&#xff0c;需要获取一些 UGC&#xff08;user generated content&#xff09;&#xff0c;包括 UP 的内容、弹幕、评论等。于是从 哔哩哔哩 (゜-゜)つロ 干杯~-bilibili 抓取了一些数据&#xff0c;以下内容仅供学习参考。 目录 1. Python 包&#xff1a;bilib…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

安卓基础(Java 和 Gradle 版本)

1. 设置项目的 JDK 版本 方法1&#xff1a;通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分&#xff0c;设置 Gradle JDK 方法2&#xff1a;通过 Settings File → Settings... (或 CtrlAltS)…...

【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统

Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...

WebRTC调研

WebRTC是什么&#xff0c;为什么&#xff0c;如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...

文件上传漏洞防御全攻略

要全面防范文件上传漏洞&#xff0c;需构建多层防御体系&#xff0c;结合技术验证、存储隔离与权限控制&#xff1a; &#x1f512; 一、基础防护层 前端校验&#xff08;仅辅助&#xff09; 通过JavaScript限制文件后缀名&#xff08;白名单&#xff09;和大小&#xff0c;提…...

CMS内容管理系统的设计与实现:多站点模式的实现

在一套内容管理系统中&#xff0c;其实有很多站点&#xff0c;比如企业门户网站&#xff0c;产品手册&#xff0c;知识帮助手册等&#xff0c;因此会需要多个站点&#xff0c;甚至PC、mobile、ipad各有一个站点。 每个站点关联的有站点所在目录及所属的域名。 一、站点表设计…...