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: 前缀 index:是一个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进行下载 如果下载很慢可用以下地址下载: https://github.com/ollama/ollama/releases/download/v0.5.7/OllamaSetup.exe 在DeepSeek官网上,你可以直接点击【model】 到达这个界面之后,…...

linux 安装启动zookeeper全过程及遇到的坑
1、下载安装zookeeper 参考文章: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,还是报错解决方法:参考…...
策略模式Spring框架下开发实例
策略类Spring框架下开发实例 先列出策略模式下需要那些类: 策略接口 (Strategy),定义所有策略类必须遵循的行为。 具体策略类(如 ConcreteStrategyA、ConcreteStrategyB),实现不同的算法或行为。 上下文类 (Context),…...
DeepSeek模型量化
技术背景 大语言模型(Large Language Model,LLM),可以通过量化(Quantization)操作来节约内存/显存的使用,并且降低了通讯开销,进而达到加速模型推理的效果。常见的就是把Float16的浮…...
【练习】【回溯:组合:不同集合】力扣 17. 电话号码的字母组合
题目 电话号码的字母组合 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 示例 1: 输入:digits “2…...

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

从WebRTC到EasyRTC:嵌入式适配的视频通话SDK实现低延迟、高稳定性音视频通信
WebRTC最初是为浏览器之间的实时通信设计的,其资源需求和复杂性可能对嵌入式设备的性能提出较高要求,因此在嵌入式系统中应用时面临一些挑战: 1)资源消耗较高 CPU和内存占用:WebRTC是一个功能强大的实时通信框架&…...

WordPress自定义排序插件:Simple Custom Post Order完全指南(SEO优化版)
在WordPress建站中,文章、分类目录或页面的默认排序方式往往无法满足个性化需求。WordPress自定义排序插件:Simple Custom Post Order插件,你可以轻松实现拖拽式自定义排序,无需修改代码即可优化内容展示逻辑。本文将详细介绍这款…...
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中有一些很精妙、便捷的设计,在了解这些数据的同时,我们可以学到如何更好的设计代码。本贴持续更新中,欢迎关注和收藏 一 QScopedPointer主要特点:示例代码 二 Q_DISABLE_COPY 一 QScopedPointer QScopedPointer 是 Qt 中的一种…...
简单工厂模式 (Simple Factory Pattern) 在Spring Boot 中的应用
简单工厂模式(Simple Factory Pattern)虽然不属于 GoF 23 种经典设计模式,但在实际开发中非常常用,尤其是在 Spring Boot 项目中。它提供了一种简单的方式来创建对象,将对象的创建逻辑集中到一个工厂类中。 一、简单工…...

《95015网络安全应急响应分析报告(2024)》
2025年2月,95015服务平台发布了最新一期的《95015网络安全应急响应分析报告(2024)》。报告分别从整体形势、受害者特征、攻击者特征等方面,对2024年95015平台接报的739起网络安全应急响应事件展开分析,并给出了7个年度…...
TensorFlow v2.16 Overview
TensorFlow v2.16 Overview 一、模块 Modules二、类 Classes三、函数 Functions TensorFlow v2.16.1 Overview 一、模块 Modules 模块是TensorFlow中组织代码的一种方式,将相关的功能和类封装在一起,方便用户使用和管理。每个模块都提供了特定领域的公共…...
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服务器已启动,监听端口 {port}...&…...
element-plus 根据条件显示多选框
代码如下: <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助手。它具有聊天机器人功能,可以与用户进行自然语言交互,回答问题、提供建议和帮助解决问题。DeepSeek 的特点包括: 强大的语言理解能力:能够理解和生成自然语言,与用户进行流畅的对话。多领域知识&…...

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

小程序的分包
1.分包的概念以及基本用法 2.在小程序项目里面添加自己的分包 3.给分包加上别名 4.查看分包体积大小 5.分包的打包原则 6.分包的引用原则 7.独立分包 8.分包的预下载...
RTSP场景下RTP协议详解及音视频打包全流程
RTSP场景下RTP协议详解及音视频打包全流程 一、RTSP与RTP的关系 RTSP:负责媒体会话控制(DESCRIBE、SETUP、PLAY、PAUSE),通过SDP协商传输参数(端口、编码格式、封装模式)。RTP:实际传输音视频数…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error
在前端开发中,JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作(如 Promise、async/await 等),开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝(r…...