15分钟学 Go 第 47 天 :并发进阶——深入了解Go语言的并发模型!
第47天的学习:并发进阶——深入了解Go语言的并发模型!
目录
- Go并发模型简介
- Goroutines深度讲解
- Channels的进阶使用
- Select语句详解
- 并发模型设计模式
- 实战案例分析
- 常见问题与解决方案
1. Go并发模型简介
Go语言以其内置的并发支持而闻名。通过轻量级的goroutine和强大的channel,Go提供了一种易于使用且高效的并发编程方法。
并发与并行的区别:
- 并发:处理多件事情的能力,但不一定同时。
- 并行:同一时刻处理多件事情。
2. Goroutines深度讲解
Goroutine是Go语言的基本单位,它比传统线程更轻量。
创建Goroutine
package mainimport ("fmt""time"
)func say(s string) {for i := 0; i < 5; i++ {fmt.Println(s)time.Sleep(100 * time.Millisecond)}
}func main() {go say("world")say("hello")
}
运行流程图
main()├─ goroutine A : say("world")└─ goroutine B : say("hello")
Goroutine的特点
- 启动goroutine使用
go
关键字。 - 不阻塞当前程序的运行。
- 实际调度由Go运行时处理。
3. Channels的进阶使用
Channels用于goroutines之间的通信。它们是类型安全的管道。
Channel的基本操作
package mainimport ("fmt"
)func sum(s []int, c chan int) {sum := 0for _, v := range s {sum += v}c <- sum
}func main() {s := []int{7, 2, 8, -9, 4, 0}c := make(chan int)go sum(s[:len(s)/2], c)go sum(s[len(s)/2:], c)x, y := <-c, <-cfmt.Println(x, y, x+y)
}
Channel类型
- 无缓冲Channel:通信是同步的。
- 缓冲Channel:可以异步通信。
市场管理员求和的例子
- **设想场景:**市场末端有多个传感器会自动将商品数量推送到中央系统,由系统统计总和。
操作 | 解释 |
---|---|
创建Channel | c := make(chan int) |
发送数据 | c <- x (在goroutine中执行) |
接收数据 | x := <-c |
4. Select语句详解
select
语句类似于 switch
,但用于Channels操作。
package mainimport ("fmt""time"
)func fibonacci(c, quit chan int) {x, y := 0, 1for {select {case c <- x:x, y = y, x+ycase <-quit:fmt.Println("quit")return}}
}func main() {c := make(chan int)quit := make(chan int)go func() {for i := 0; i < 10; i++ {fmt.Println(<-c)}quit <- 0}()fibonacci(c, quit)
}
作用:
- 多路复用:监听多个Channel。
- 处理超时:结合
time.After
实现超时控制。
5. 并发模型设计模式
工作池模型
用于限制同时运行的goroutines数目。
package mainimport ("fmt""time"
)func worker(id int, jobs <-chan int, results chan<- int) {for j := range jobs {fmt.Printf("worker %d started job %d\n", id, j)time.Sleep(time.Second)fmt.Printf("worker %d finished job %d\n", id, j)results <- j * 2}
}func main() {const numJobs = 5jobs := make(chan int, numJobs)results := make(chan int, numJobs)for w := 1; w <= 3; w++ {go worker(w, jobs, results)}for j := 1; j <= numJobs; j++ {jobs <- j}close(jobs)for a := 1; a <= numJobs; a++ {<-results}
}
Pipeline模式
用于串联多个处理阶段。
package mainimport ("fmt"
)func gen(nums ...int) <-chan int {out := make(chan int)go func() {for _, n := range nums {out <- n}close(out)}()return out
}func sq(in <-chan int) <-chan int {out := make(chan int)go func() {for n := range in {out <- n * n}close(out)}()return out
}func main() {c := gen(2, 3, 4)out := sq(c)for n := range out {fmt.Println(n)}
}
6. 实战案例分析
为了进一步巩固理解,我们来看一个具体的并发应用示例。
案例:并发Web爬虫
- 目标:使用并发从多个URL抓取页面标题。
package mainimport ("fmt""net/http""io/ioutil""regexp""time"
)func fetch(url string, ch chan<- string) {start := time.Now()resp, err := http.Get(url)if err != nil {ch <- fmt.Sprintf("Error: %s", err)return}defer resp.Body.Close()body, err := ioutil.ReadAll(resp.Body)if err != nil {ch <- fmt.Sprintf("Error reading body: %s", err)return}re := regexp.MustCompile("<title>(.*?)</title>")matches := re.FindStringSubmatch(string(body))title := "No title found"if len(matches) > 1 {title = matches[1]}secs := time.Since(start).Seconds()ch <- fmt.Sprintf("%.2f seconds: %s", secs, title)
}func main() {urls := []string{"https://golang.org","https://godoc.org","https://gopl.io","https://play.golang.org",}ch := make(chan string)for _, url := range urls {go fetch(url, ch)}for range urls {fmt.Println(<-ch)}
}
7. 常见问题与解决方案
在学习并发时,你可能会遇到以下问题:
死锁问题
- 原因:两个goroutine相互等待对方释放资源。
- 解决方法:确保总是有一个goroutine能继续推进。
资源竞争
- 原因:多个goroutine试图同时访问同一个资源。
- 解决方法:使用channel同步,或者使用
sync.Mutex
。
Goroutine泄漏
- 原因:goroutine等待无法到达的事件。
- 解决方法:确保所有channels都能正确关闭。
总结
今天我们深入探讨了Go语言的并发模型。理解如何有效地创建和管理Goroutines和Channels是写出高效并发程序的关键。通过示例代码和设计模式,你学会了如何利用Go的并发特性来解决复杂的问题。
怎么样今天的内容还满意吗?再次感谢观众老爷的观看,关注GZH:凡人的AI工具箱,回复666,送您价值199的AI大礼包。最后,祝您早日实现财务自由,还请给个赞,谢谢!
相关文章:
15分钟学 Go 第 47 天 :并发进阶——深入了解Go语言的并发模型!
第47天的学习:并发进阶——深入了解Go语言的并发模型! 目录 Go并发模型简介Goroutines深度讲解Channels的进阶使用Select语句详解并发模型设计模式实战案例分析常见问题与解决方案 1. Go并发模型简介 Go语言以其内置的并发支持而闻名。通过轻量级的g…...

前端代码分析题(选择题、分析题)——this指向、原型链分析
this指向 普通函数:this 的指向由调用方式决定,可以是全局对象、调用该函数的对象,或者显式指定的对象。箭头函数:this 的指向在定义时确定,始终继承自外层函数作用域的 this,不会被调用方式影响。 var obj…...
react 组件应用
文章目录 react 组件react 中组件 hook 函数应用useMemo技术细节(useMemo 钩子函数和 useCallback 钩子函数)小结(依赖性数组应用) react 组件 函数式组件实例及应用场景 实例: 以下是一个简单的函数式组件,用于显示一个欢迎消息。 import React from re…...
mysql 快速解决死锁方式
mysql 快速解决死锁方式 直接寻找并终止导致死锁的具体 SQL 语句是处理死锁的一种有效方法,特别是在高并发环境中。以下步骤和示例展示了如何通过识别、分析和终止长时间运行的 SQL 语句来解决死锁问题。 一、识别那个导致死锁的 SQL 语句 1. 使用 SHOW ENGINE I…...

RabbitMQ 篇-深入了解 RabbitMQ 安装以及 SpringAMQP 的基础使用(声明队列和交换机、发送接收消息、配置 JSON 消息转化器)
🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 RabbitMQ 初识 1.1 RabbitMQ 安装 2.0 数据隔离 2.1 用户管理 2.2 virtual host 虚拟主机 3.0 SpringAMQP 3.1 RabbitMQ 配置 3.2 发送消息 3.3 接收消息 3.4 Wor…...

在 WPF 中,绑定机制是如何工作的?WPF数据绑定机制解析
在WPF(Windows Presentation Foundation)中,数据绑定机制是其核心功能之一,广泛用于连接应用程序的UI(用户界面)和应用程序的业务逻辑层。数据绑定允许你将UI元素与数据源(如对象、集合或其他数…...
pwn学习笔记(12)--Chunk Extend and Overlapping
pwn学习笔记(12)–Chunk Extend and Overlapping chunk extend 是堆漏洞的一种常见利用手法,通过 extend 可以实现 chunk overlapping(块重叠) 的效果。这种利用方法需要以下的时机和条件: 程序中存在…...
java基础面试题六集合框架
目录 1. List,Set,Map是否继承自collection接口? 2. 说说List,Set,Map三者的区别 3. 写出list、map、set接口的实现类,并说出其特点 4. 常见集合类的区别和适用场景 5. 集合的父类是谁?哪些安全的? 6…...

2024年12月一区SCI-指数-三角优化算法ETO-附Matlab免费代码
引言 本期介绍了一种基于数学概念的元启发式优化算法,称为指数-三角优化算法Exponential-trigonometric optimization algorithm,ETO。该算法基于指数函数和三角函数的复杂组合,于2024年12月最新发表在中JCR1区、 中科院1区 SCI期刊Computer…...
设置服务器ssh连接超时时间
在Linux服务器上,您可以通过修改SSH服务器配置文件来设置SSH连接的超时时间。以下是设置SSH连接超时时间的一些步骤: 打开SSH服务器配置文件。这个文件通常是/etc/ssh/sshd_config。sudo nano /etc/ssh/sshd_config在配置文件中,您可以设置以…...

Dubbo分布式日志跟踪实现
前言 随着越来越多的应用逐渐微服务化后,分布式服务之间的RPC调用使得异常排查的难度骤增,最明显的一个问题,就是整个调用链路的日志不在一台机器上,往往定位问题就要花费大量时间。如何在一个分布式网络中把单次请求的整个调用日…...

EPSON机械手与第三方相机的校准功能设计By python
EPSON机械手与第三方相机的校准功能设计By python 使用Python来实现EPSON机械手与第三方相机的校准功能是一个复杂但可行的任务。这通常涉及以下几个步骤:硬件接口通信、图像处理、标定算法实现和控制逻辑编写。 1. 环境准备 首先,库 pip install numpy opencv-python pyse…...
探索 Java 23:新时代的编程利器
一、引言 随着技术的不断发展,Java 作为一种广泛应用的编程语言也在不断演进。Java 23 的推出带来了许多令人兴奋的新特性和改进,为开发者提供了更多的工具和功能,以应对日益复杂的软件开发挑战。本文将深入介绍 Java 23 的各个方面。 二、J…...
CSS3_3D变换(七)
1、CSS3_3D变换 1.1 3D空间与景深 3D空间:在父元素中将属性transform-style设置为preserve-3d开启3D空间,默认值为flat(开启2D空间); 景深:人眼与平面的距离,产生透视效果,使得效果…...

Mesh网格
Mesh(网格) 定义:Mesh 是一个包含顶点、三角形、顶点法线、UV坐标、颜色和骨骼权重等数据的对象。它定义了3D模型的几何形状。 功能: 顶点(Vertices):构成3D模型的点。 三角形(Triangles)&…...

LeetCode 509.斐波那契数
动态规划思想 五步骤: 1.确定dp[i]含义 2.递推公式 3.初始化 4.遍历顺序 5.打印dp数组 利用状态压缩,简化空间复杂度。在原代码中,dp 数组保存了所有状态,但实际上斐波那契数列的计算只需要前两个状态。因此,我们…...
SQL Server 数据太多如何优化
大家好,我是 V 哥。讲了很多数据库,有小伙伴说,SQL Server 也讲一讲啊,好吧,V 哥做个听话的门童,今天要聊一聊 SQL Server。 在 SQL Server 中,当数据量增大时,数据库的性能可能会受…...

关于word 页眉页脚的一些小问题
去掉页眉底纹: 对文档的段落边框和底纹进行设置,也是页眉横线怎么删除的一种解决方式,具体操作如下: 选中页眉中的横线文本; 点击【开始】选项卡,在【段落】组中点击【边框】按钮的下拉箭头; …...
【高等数学学习记录】连续函数的运算与初等函数的连续性
一、知识点 (一)连续函数的和、差、积、商的连续性 定理1 设函数 f ( x ) f(x) f(x) 和 g ( x ) g(x) g(x) 在点 x 0 x_0 x0 连续,则它们的和(差) f g f\pm g fg、积 f ⋅ g f\cdot g f⋅g 及商 f g \frac{f…...

【抖音直播间弹幕】protobuf协议分析
将Uint8Array变成 PushFrame格式,里面的payload就存放着弹幕消息 点进去就可以看到其定义的proto结构 headers是一个自定义类型 将测试数据保存一下,等下做对比 先将PushFrame的 payload 内容进行gzip解压 然后再解析为响应 可以看到里面有对应的消…...

Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...

【51单片机】4. 模块化编程与LCD1602Debug
1. 什么是模块化编程 传统编程会将所有函数放在main.c中,如果使用的模块多,一个文件内会有很多代码,不利于组织和管理 模块化编程则是将各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数声明,其他.c文…...