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

go 并发 gorouting chan channel select Mutex sync.One

goroutine

// head: 前缀  index:是一个int的指针
func print(head string, index *int) {for i := 0; i < 5; i++ {// 指针对应的int ++*index++fmt.Println(*index, head, i)// 暂停1stime.Sleep(1 * time.Second)}
}/*
Go 允许使用 go 语句开启一个新的运行期线程,即 goroutine
以一个不同的、新创建的 goroutine 来执行一个函数
同一个程序中的所有 goroutine 共享同一个地址空间。
*/
func main() {fmt.Println("main ...")index := 0go print("first", &index)go print("second", &index)time.Sleep(6 * time.Second)fmt.Println("success ...")
}

chan 一般用法

// 求和,并将数据放在channel中
func sum(arr []int, resultChan chan int) {if len(arr) <= 0 {resultChan <- 0return}var sum = 0for _, value := range arr {sum += value}fmt.Println(sum)// 将结果放在channel中resultChan <- sum
}/*
channel 用于 goroutine之间进行通信1. 创建channelch1 := make(chan 类型)  默认是没有缓冲区的ch2 := make(chan 类型, 缓存长度)2. 添加数据到channel中ch1 <- 1233. 从channel中获取数据var value = <- ch1有无缓冲区区别:
1. 没有缓冲区 按照缓冲区为1来处理,即channel只能放一个数据
2. channel满了后就会阻塞,直到有空位才可以继续放入数据
3. 获取数据类似,阻塞到channel中有数据
*/
func main() {fmt.Println("main ...")// 创建一个没有缓冲区的channelresultChan := make(chan int)array1 := []int{10, 20, 30}array2 := []int{1, 2, 3}// 给两个数组求和并将结果放在channel中go sum(array1, resultChan)go sum(array2, resultChan)// 从channel中获取两个数据,打印到consolefmt.Println(<-resultChan, <-resultChan)fmt.Println("continue ...")// 如果继续获取则会报错:fatal error: all goroutines are asleep - deadlock!// fmt.Println(<-resultChan)fmt.Println("success ...")
}

无缓冲区的chan只能结合goroutine使用

func main() {fmt.Println("main ...")// 创建一个没有缓冲区的channelresultChan := make(chan int)// chan 只能结合goroutine来使用,否则报错// fatal error: all goroutines are asleep - deadlock!resultChan <- 10fmt.Println(<-resultChan)fmt.Println("success ...")
}

有缓冲区的chan可直接赋值

func main() {fmt.Println("main ...")// 创建一个有缓冲区的channelch := make(chan int, 2)ch <- 1ch <- 2fmt.Println(<-ch)fmt.Println(<-ch)fmt.Println("success ...")
}

for rang获取channel数据

func addData(ch chan int, len int) {for i := 0; i < len; i++ {ch <- i}// 如果不关闭,for val := range ch 会阻塞获取数据close(ch)
}/*- 可以使用rang遍历channel,如果channel关闭则直接结束,否则会阻塞等待数据的输入for val := range ch
*/
func main() {fmt.Println("main ...")// 创建一个有缓冲区的channellen := 5ch := make(chan int, len)go addData(ch, len)for val := range ch {fmt.Println(val)}fmt.Println("success ...")
}

select **等待多个goroutine

select可以等待多个goroutine,会阻塞一直到某个case不在阻塞。

func print1(header string, ch1, ch2 chan int) {for i := 0; i < len; i++ {select {case val := <-ch1:fmt.Println(header, val)time.Sleep(time.Second)case ch2 <- i:// do nothing}}
}func main() {fmt.Println("main ...")ch1 := make(chan int)ch2 := make(chan int)go print1("f1", ch1, ch2)go print1("f2", ch2, ch1)time.Sleep(6 * time.Second)fmt.Println("success ...")
}

WaitGroup等待所有goroutine完成

类似java中的CountDownLatch

// 不怎么理解为什么group要用指针
func work(index int, wg *sync.WaitGroup) {defer wg.Done()fmt.Println(index)time.Sleep(time.Second)
}func main() {fmt.Println("main ...")var wg sync.WaitGroupfor i := 0; i < 5; i++ {wg.Add(1)// 为什么要将wg的指针传过去go work(i, &wg)}// 阻塞到所有的goroutine完成后wg.Wait()fmt.Println("success ...")
}

并发锁Mutex

type ConcurrentMap struct {lock    sync.Mutexhashmap map[string]int
}// 1. cm *ConcurrentMap 要传指针,否则操作的是副本
// 2. wg *sync.WaitGroup 这个也传指针,确保操作的是一个对象
func (cm *ConcurrentMap) inc(index int, key string, wg *sync.WaitGroup) {defer wg.Done()fmt.Println(index, "start")cm.lock.Lock()before := cm.hashmap[key]fmt.Println(index, "before", before)cm.hashmap[key] = cm.hashmap[key] + 1time.Sleep(time.Microsecond * 100)after := cm.hashmap[key]fmt.Println(index, "after", after)if before+1 != after {fmt.Println(index, "error >>>>>")}cm.lock.Unlock()fmt.Println(index, "end")
}func main() {fmt.Println("main ...")cm := ConcurrentMap{hashmap: make(map[string]int)}var wg sync.WaitGroupfor i := 0; i < 3; i++ {wg.Add(1)go cm.inc(i, "apple", &wg)}wg.Wait()fmt.Println("success ...", cm.hashmap["apple"])
}

RWMutex 读写锁子

参考:

https://www.jianshu.com/p/679041bdaa39

sync.Once 配置文件只加载一次

需求:获取配置文件,如果没有价值只就加载

写法1:

func initMap() {if hasInitMap {return}initMapLock.Lock()defer initMapLock.Unlock()if !hasInitMap {fmt.Println("init map")m = map[string]string{"aaa": "111","bbb": "22",}hasInitMap = true}
}func getValue1(key string) string {initMap()return m[key]
}

写法2:

// 定义一次执行对象
var once sync.Oncefunc initMap2() {m = map[string]string{"aaa": "111","bbb": "22",}
}func getValue2(key string) string {// 一次执行once.Do(initMap2)return m[key]
}func main() {fmt.Println("main ...")for i := 0; i < 20; i++ {fmt.Println(getValue1("aaa"))fmt.Println(getValue2("aaa"))}fmt.Println("success ...")
}

sync.Map 类型ConcurrentHashMap

是安全的Map

atomic.AddInt64(&intV,1) 对基础类型安全操作方法

多线程给变量递增: intV := 3

1. 直接+1 线程不安全

2. 使用Mutex锁代价太大

3. 使用atomic包的方法最好,类似Java中的Atomic

参考

https://blog.csdn.net/weixin_53623989/article/details/136209823

https://blog.csdn.net/e2788666/article/details/130644433

相关文章:

go 并发 gorouting chan channel select Mutex sync.One

goroutine // head&#xff1a; 前缀 index&#xff1a;是一个int的指针 func print(head string, index *int) {for i : 0; i < 5; i {// 指针对应的int *indexfmt.Println(*index, head, i)// 暂停1stime.Sleep(1 * time.Second)} }/* Go 允许使用 go 语句开启一个新的运…...

亲测Windows部署Ollama+WebUI可视化

一. Ollama下载 登录Ollama官网(Ollama)点击Download进行下载 如果下载很慢可用以下地址下载&#xff1a; https://github.com/ollama/ollama/releases/download/v0.5.7/OllamaSetup.exe 在DeepSeek官网上&#xff0c;你可以直接点击【model】 到达这个界面之后&#xff0c;…...

linux 安装启动zookeeper全过程及遇到的坑

1、下载安装zookeeper 参考文章&#xff1a;https://blog.csdn.net/weixin_48887095/article/details/132397448 2、启动失败 1、启动失败JAVA_HOME is not set and java could not be found in PATH 已安装 JAVA 配置了JAVA_HOME,还是报错解决方法&#xff1a;参考&#xf…...

策略模式Spring框架下开发实例

策略类Spring框架下开发实例 先列出策略模式下需要那些类: 策略接口 (Strategy)&#xff0c;定义所有策略类必须遵循的行为。 具体策略类&#xff08;如 ConcreteStrategyA、ConcreteStrategyB&#xff09;&#xff0c;实现不同的算法或行为。 上下文类 (Context)&#xff0c;…...

DeepSeek模型量化

技术背景 大语言模型&#xff08;Large Language Model&#xff0c;LLM&#xff09;&#xff0c;可以通过量化&#xff08;Quantization&#xff09;操作来节约内存/显存的使用&#xff0c;并且降低了通讯开销&#xff0c;进而达到加速模型推理的效果。常见的就是把Float16的浮…...

【练习】【回溯:组合:不同集合】力扣 17. 电话号码的字母组合

题目 电话号码的字母组合 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 示例 1&#xff1a; 输入&#xff1a;digits “2…...

分布式文件系统HDFS

一、HDFS简介 HDFS&#xff08; Hadoop Distributed File System &#xff09;&#xff0c;意为&#xff1a;Hadoop分布式文件系统。是Apache Hadoop核心组件之一&#xff0c;作为大数据生态圈最底层的分布式存储服务而存在。分布式文件系统解决大数据如何存储问题。分布式意味…...

从WebRTC到EasyRTC:嵌入式适配的视频通话SDK实现低延迟、高稳定性音视频通信

WebRTC最初是为浏览器之间的实时通信设计的&#xff0c;其资源需求和复杂性可能对嵌入式设备的性能提出较高要求&#xff0c;因此在嵌入式系统中应用时面临一些挑战&#xff1a; 1&#xff09;资源消耗较高 CPU和内存占用&#xff1a;WebRTC是一个功能强大的实时通信框架&…...

WordPress自定义排序插件:Simple Custom Post Order完全指南(SEO优化版)

在WordPress建站中&#xff0c;文章、分类目录或页面的默认排序方式往往无法满足个性化需求。WordPress自定义排序插件&#xff1a;Simple Custom Post Order插件&#xff0c;你可以轻松实现拖拽式自定义排序&#xff0c;无需修改代码即可优化内容展示逻辑。本文将详细介绍这款…...

docker安装ros2 并在windows中显示docker内ubuntu系统窗口并且vscode编程

这里包括docker desktop安装ros2 humble hawkshill , 安装xserver(用来在windows中显示ubuntu中窗口), vscode安装插件连接docker并配置python的一系列方法 1.安装xserver 为了能方便的在windows中显示ubuntu内的窗口,比如rqt窗口 参考文章:https://www.cnblogs.com/larva-zhh…...

【QT中的一些高级数据结构,持续更新中...】

QT中有一些很精妙、便捷的设计&#xff0c;在了解这些数据的同时&#xff0c;我们可以学到如何更好的设计代码。本贴持续更新中&#xff0c;欢迎关注和收藏 一 QScopedPointer主要特点&#xff1a;示例代码 二 Q_DISABLE_COPY 一 QScopedPointer QScopedPointer 是 Qt 中的一种…...

简单工厂模式 (Simple Factory Pattern) 在Spring Boot 中的应用

简单工厂模式&#xff08;Simple Factory Pattern&#xff09;虽然不属于 GoF 23 种经典设计模式&#xff0c;但在实际开发中非常常用&#xff0c;尤其是在 Spring Boot 项目中。它提供了一种简单的方式来创建对象&#xff0c;将对象的创建逻辑集中到一个工厂类中。 一、简单工…...

《95015网络安全应急响应分析报告(2024)》

2025年2月&#xff0c;95015服务平台发布了最新一期的《95015网络安全应急响应分析报告&#xff08;2024&#xff09;》。报告分别从整体形势、受害者特征、攻击者特征等方面&#xff0c;对2024年95015平台接报的739起网络安全应急响应事件展开分析&#xff0c;并给出了7个年度…...

TensorFlow v2.16 Overview

TensorFlow v2.16 Overview 一、模块 Modules二、类 Classes三、函数 Functions TensorFlow v2.16.1 Overview 一、模块 Modules 模块是TensorFlow中组织代码的一种方式&#xff0c;将相关的功能和类封装在一起&#xff0c;方便用户使用和管理。每个模块都提供了特定领域的公共…...

Udp发送和接收数据(python和QT)

服务端代码 (python) import socketdef udp_server(host0.0.0.0, port12345):# 创建一个UDP套接字sock socket.socket(socket.AF_INET, socket.SOCK_DGRAM)# 绑定服务器的IP地址和端口号sock.bind((host, port))print(f"UDP服务器已启动&#xff0c;监听端口 {port}...&…...

element-plus 根据条件显示多选框

代码如下&#xff1a; <el-table :data"pager.lists" selection-change"handleSelectionChange" row-key"id" :tree-props"{ checkStrictly: true }" :cell-class-name"cellClass"> <el-table-column type"s…...

Ubuntu 22.04 Install deepseek

前言 deepseekAI助手。它具有聊天机器人功能&#xff0c;可以与用户进行自然语言交互&#xff0c;回答问题、提供建议和帮助解决问题。DeepSeek 的特点包括&#xff1a; 强大的语言理解能力&#xff1a;能够理解和生成自然语言&#xff0c;与用户进行流畅的对话。多领域知识&…...

DeepSeek赋能智慧文旅:新一代解决方案,重构文旅发展的底层逻辑

DeepSeek作为一款前沿的人工智能大模型&#xff0c;凭借其强大的多模态理解、知识推理和内容生成能力&#xff0c;正在重构文旅产业的发展逻辑&#xff0c;推动行业从传统的经验驱动向数据驱动、从人力密集型向智能协同型转变。 一、智能服务重构&#xff1a;打造全域感知的智…...

小程序的分包

1.分包的概念以及基本用法 2.在小程序项目里面添加自己的分包 3.给分包加上别名 4.查看分包体积大小 5.分包的打包原则 6.分包的引用原则 7.独立分包 8.分包的预下载...

RTSP场景下RTP协议详解及音视频打包全流程

RTSP场景下RTP协议详解及音视频打包全流程 一、RTSP与RTP的关系 RTSP&#xff1a;负责媒体会话控制&#xff08;DESCRIBE、SETUP、PLAY、PAUSE&#xff09;&#xff0c;通过SDP协商传输参数&#xff08;端口、编码格式、封装模式&#xff09;。RTP&#xff1a;实际传输音视频数…...

web vue 项目 Docker化部署

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

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具&#xff0c;可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件&#xff0c;也不需要在线上传文件&#xff0c;保护您的隐私。 工具截图 主要特点 &#x1f680; 快速转换&#xff1a;本地转换&#xff0c;无需等待上…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...

MySQL:分区的基本使用

目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区&#xff08;Partitioning&#xff09;是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分&#xff08;分区&#xff09;可以独立存储、管理和优化&#xff0c;…...

Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合

作者&#xff1a;来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布&#xff0c;Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明&#xff0c;Elastic 作为 …...