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

go的slice学习

并发访问slice

线上出现一粒多协程并发append全局slice的情况,导致内存不断翻倍,因此对slice的使用需要重新考虑。
并发读写的情况下, 可以利用锁、channel等避免竞态

问题

func TestDemo32(t *testing.T) {var wg sync.WaitGroupvar n = 100s := make([]int, 0, 200)hdr := (*reflect.SliceHeader)(unsafe.Pointer(&s))fmt.Printf("Data addr: %d\n", hdr.Data)fmt.Printf("Data cap: %d\n", hdr.Cap)fmt.Printf("Data len: %d\n", hdr.Len)wg.Add(n)for i := 1; i <= n; i++ {go func(v int) {defer wg.Done()s = append(s, v)}(i)}wg.Wait()hdr = (*reflect.SliceHeader)(unsafe.Pointer(&s))fmt.Printf("Data addr: %d\n", hdr.Data)fmt.Printf("Data cap: %d\n", hdr.Cap)fmt.Printf("Data len: %d\n", hdr.Len)fmt.Println(jsonx.ToString(s))// Data addr: 824645965056// Data cap: 200// Data len: 0// Data addr: 824645965056// Data cap: 200// Data len: 96
}func TestDemo33(t *testing.T) {var wg sync.WaitGroupvar n = 500s := make([]int, 0, 10)hdr := (*reflect.SliceHeader)(unsafe.Pointer(&s))fmt.Printf("Data addr: %d\n", hdr.Data)fmt.Printf("Data cap: %d\n", hdr.Cap)fmt.Printf("Data len: %d\n", hdr.Len)wg.Add(n)for i := 1; i <= n; i++ {go func(v int) {defer wg.Done()s = append(s, v)}(i)}wg.Wait()hdr = (*reflect.SliceHeader)(unsafe.Pointer(&s))fmt.Printf("Data addr: %d\n", hdr.Data)fmt.Printf("Data cap: %d\n", hdr.Cap)fmt.Printf("Data len: %d\n", hdr.Len)fmt.Println(jsonx.ToString(s))// Data addr: 824635459136// Data cap: 10// Data len: 0// Data addr: 824665328128// Data cap: 672// Data len: 453
}

Go语言中的slice是一种引用类型,它本身不保存任何元素,只是对数组的引用。
append操作的主要功能是向slice添加元素。
如果slice的底层数组容量足够,就直接添加;如果不够,就会先分配新的底层数组,然后将原有的元素和新添加的元素一起拷贝到新数组,在这个过程中,原有的底层数组会被垃圾回收。

当底层数组的容量不足以容纳新的元素时,就会产生新的底层数组
此时原有的slice和返回的新的slice,其底层数组是不同的。
这也是为什么在使用append时,总是习惯性地将结果再次赋值给原slice。

方案一 channel

func TestDemo(t *testing.T) {// 无缓冲,发送侧有数据,接收侧才执行// 用于做同步c := make(chan struct{})// new 了该 job 后,该 job 就开始准备从 channel 接收数据s := NewScheduleJob(n, func() { c <- struct{}{} })// 并发发送数据到channelvar wg sync.WaitGroupvar n  = 1000wg.Add(n)for i := 0; i < n; i++ {go func(v int) {defer wg.Done()s.AddData(v)}(i)}// 等待上述多个协程将数据存入slicewg.Wait()// 发送完之后关闭channels.Close()// 阻塞在这里是等待NewScheduleJob执行结束<-c// 最终实现读写一致fmt.Println(len(s.data))
}type ServiceData struct {ch   chan int // 用来同步的channeldata []int    // 存储数据的slice
}// Schedule 从 channel 接收数据串行存入slice,直到ch关闭
func (s *ServiceData) Schedule() {for i := range s.ch {s.data = append(s.data, i)}
}// Close 关闭channel
func (s *ServiceData) Close() {close(s.ch)
}// AddData 发送数据到 channel
func (s *ServiceData) AddData(v int) {s.ch <- v
}func NewScheduleJob(size int, done func()) *ServiceData {s := &ServiceData{ch:   make(chan int, size),data: make([]int, 0),}go func() {// 并发地 append 数据到 slice// Schedule 从 channel 接收数据串行存入slice,直到ch关闭s.Schedule()// 通知主协程继续执行done()}()return s
}

优点:逻辑复杂,适用于高并发场景

方案二 - 锁

func main() {slc := make([]int, 0, 1000)var wg sync.WaitGroupvar lock sync.Mutexfor i := 0; i < 1000; i++ {wg.Add(1)go func(a int) {defer wg.Done()lock.Lock()defer lock.Unlock()slc = append(slc, a)}(i)}wg.Wait()fmt.Println(len(slc))
}

优点:锁的逻辑重,适用于对性能要求不高的场景

学习文档

https://juejin.cn/post/6844904134592692231

相关文章:

go的slice学习

并发访问slice 线上出现一粒多协程并发append全局slice的情况&#xff0c;导致内存不断翻倍&#xff0c;因此对slice的使用需要重新考虑。 并发读写的情况下&#xff0c; 可以利用锁、channel等避免竞态 问题 func TestDemo32(t *testing.T) {var wg sync.WaitGroupvar n 1…...

软件设计师17--磁盘管理

软件设计师17--磁盘管理 考点1&#xff1a;存储管理 - 磁盘管理调度算法磁盘调度 - FCFS磁盘调度 - SSTF例题&#xff1a; 考点1&#xff1a;存储管理 - 磁盘管理 存取时间寻道时间等待时间&#xff0c;训导时间是指磁头移动到磁道所需的时间&#xff1b;等待时间为等待读写的扇…...

学点Java打小工——Day2Day3一点作业

1 猜数字&#xff08;10次机会&#xff09; 随机生成[1,1000]的一个数&#xff0c;输入你猜的数程序会给出反馈&#xff0c;直到猜对或次数用尽(10次)。 //猜数字 10次机会Testpublic void guessNumber() {Random random new Random();// [0, 1000) 1// [1, 1000]int num ra…...

【话题】2024年AI辅助研发趋势,有那些应用领域

大家好&#xff0c;我是全栈小5&#xff0c;欢迎阅读文章&#xff01; 此篇是【话题达人】系列文章&#xff0c;这一次的话题是《2024年AI辅助研发趋势》 目录 背景概念实践医药领域汽车设计领域展望未来文章推荐 背景 随着人工智能技术的持续发展与突破&#xff0c;2024年AI辅…...

蓝桥杯——数组切分

数组切分 题目分析 这里要搞清楚一个点就是满足区间内数字是连续数字的区间有什么样的特点&#xff0c;既然数字连续重新排列后的数字为n,n1,n2,n3,n4,…nlen&#xff0c;则最大数字和最小数字之差恰好是区间长度减1&#xff0c;即nlen-nlen&#xff0c;同样因为下标也是连续…...

【机器学习】进阶学习:详细解析Sklearn中的MinMaxScaler---原理、应用、源码与注意事项

【机器学习】进阶学习&#xff1a;详细解析Sklearn中的MinMaxScaler—原理、应用、源码与注意事项 这篇文章的质量分达到了97分&#xff0c;虽然满分是100分&#xff0c;但已经相当接近完美了。请您耐心阅读&#xff0c;我相信您一定能从中获得不少宝贵的收获和启发~ &#x1f…...

数据库是什么?数据库连接、管理与分析工具推荐

一、数据库是什么&#xff1f; 数据库是一种结构化的数据存储系统&#xff0c;用于有效地组织、存储和管理大量的数据。它是一个集中化的数据存储库&#xff0c;通常由一个或多个数据表组成&#xff0c;每个数据表包含多个行和列&#xff0c;用于存储特定类型的数据。数据表中…...

【C#算法实现】可见的山峰对数量

文章目录 前言一、题目要求二、算法设计及代码实现2.1 算法思想2.2 代码实现 前言 本文是【程序员代码面试指南&#xff08;第二版&#xff09;学习笔记】C#版算法实现系列之一&#xff0c;用C#实现了《程序员代码面试指南》&#xff08;第二版&#xff09;栈和队列中的可见的…...

Selenium 隐藏浏览器指纹特征的几种方式

文章转载于&#xff1a;https://mp.weixin.qq.com/s/sXRXwMDqekUHfU2SnL-PYg 我们使用 Selenium 对网页进行爬虫时&#xff0c;如果不做任何处理直接进行爬取&#xff0c;会导致很多特征是暴露的 对一些做了反爬的网站&#xff0c;做了特征检测&#xff0c;用来阻止一些恶意爬虫…...

k8s发布nacos-server,nodeport配置注意事项

k8s发布nacos-server注册不上问题 问题描述&#xff1a;分析过程&#xff1a; 问题描述&#xff1a; k8s发布nacos-server做服务公用使用&#xff0c;nodeport暴漏服务给客户端注册&#xff0c; nacos:端口 8848&#xff1a;30601 9848&#xff1a;30701 分析过程&#xff1a…...

伪分布式Spark集群搭建

一、软件环境 软 件 版 本 安 装 包 VMware虚拟机 16 VMware-workstation-full-16.2.2-19200509.exe SSH连接工具 FinalShell Linux OS CentOS7.5 CentOS-7.5-x86_64-DVD-1804.iso JDK 1.8 jdk-8u161-linux-x64.tar.gz Spark 3.2.1 spark-3.2.1-bin-…...

Android 监听卫星导航系统状态及卫星测量数据变化

源码 package com.android.circlescalebar;import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import android.Manifest; import android.conte…...

鸿蒙培训开发:就业市场的新热点~

金三银四在即&#xff0c;随着春节假期结束&#xff0c;各行各业纷纷复工复产&#xff0c;2024年的春季招聘市场也迎来了火爆的局面。最近发布的《2024年春招市场行情周报&#xff08;第一期&#xff09;》显示&#xff0c;尽管整体就业市场仍处于人才饱和状态&#xff0c;但华…...

【C++】string的底层剖析以及模拟实现

一、字符串类的认识 C语言中&#xff0c;字符串是以\0结尾的一些字符的集合&#xff0c;为了操作方便&#xff0c;C标准库中提供了一些str系列的库函数&#xff0c; 但是这些库函数与字符串是分离开的&#xff0c;不太符合OOP的思想&#xff0c;而且底层空间需要用户自己管理&a…...

Unity的PICO项目基础环境搭建笔记(调试与构建应用篇)

文章目录 前言一、为设备开启开发者模式1、开启PICO VR一体机。前往设置>通用>关于本机>软件版本号2、一直点击 软件版本号 &#xff0c;直到出现 开发者 选项3、进入 开发者模式&#xff0c;打开 USB调试&#xff0c;选择 文件传输 二、实时预览应用场景1、下载PC端的…...

电脑远程桌面选项变成灰色没办法勾选怎么办?

有些人在使用Windows系统自带的远程桌面工具时&#xff0c;会发现系统属性远程桌面选项卡中勾选启用“允许远程连接到此计算机”。 导致此问题出现的原因主要是由于组策略或者注册表设置错误造成的。 修复远程桌面选项变灰的两种方法&#xff01; 方法一&#xff1a;设置本地组…...

2024.3.14

1.成员函数版本实现算术运算符的重载,全局函数版本实现算术运算符的重载 #include <iostream>using namespace std;class Room {friend const Room operator-(const Room &a,const Room &b); private:string a;int b; public:Room(){}Room(string a,int b):a(a)…...

chatGPT的耳朵!OpenAI的开源语音识别AI:Whisper !

语音识别是通用人工智能的重要一环&#xff01;可以说是AI的耳朵&#xff01; 它可以让机器理解人类的语音&#xff0c;并将其转换为文本或其他形式的输出。 语音识别的应用场景非常广泛&#xff0c;比如智能助理、语音搜索、语音翻译、语音输入等等。 然而&#xff0c;语音…...

C语言冒泡排序

冒泡排序是一种简单的排序算法&#xff0c;通过重复遍历要排序的数列&#xff0c;依次比较两个相邻的元素&#xff0c;如果它们的顺序错误则交换它们。这个过程会重复进行&#xff0c;直到没有相邻的元素需要交换&#xff0c;也就是数列已经排序完成。 冒泡排序的名字来源于其工…...

vue2 elementui 封装一个动态表单复杂组件

封装一个动态表单组件在 Vue 2 和 Element UI 中需要考虑到表单字段的动态添加、删除以及验证等复杂功能。下面是一个简单的例子&#xff0c;展示如何创建一个可以动态添加和删除字段的表单组件。 首先&#xff0c;你需要安装并引入 Element UI&#xff1a; bash 复制 npm in…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...