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

Golang并发机制及CSP并发模型

Golang 并发机制及 CSP 并发模型

Golang 是一门为并发而生的语言,其并发机制基于 CSP(Communicating Sequential Processes,通信顺序过程) 模型。CSP 是一种描述并发系统中交互模式的正式语言,强调通过通信来共享内存,而不是通过共享内存来通信。
在这里插入图片描述


CSP 模型简介

CSP 模型由 Tony Hoare 在 20 世纪 70 年代提出,是一种基于消息传递的并发模型。其核心思想是:

  • 通信代替共享:并发实体(如 Goroutine)通过 Channel 进行通信,而不是直接共享内存。
  • Channel 是第一类对象:Channel 是 CSP 模型的核心,用于在并发实体之间传递消息。
  • 同步通信:发送和接收操作是阻塞的,确保消息的同步传递。

CSP 模型的优势在于:

  • 避免了传统多线程编程中的锁竞争问题。
  • 简化了并发编程的复杂性。
  • 提高了程序的可读性和可维护性。

Golang 中的 CSP 实现

Golang 通过 GoroutineChannel 实现了 CSP 模型。

1. Goroutine

Goroutine 是 Golang 中的并发执行单位,类似于线程,但比线程更轻量。其特点包括:

  • 用户态调度:Goroutine 由 Go 运行时调度,避免了内核态和用户态的切换开销。
  • 低成本创建:每个 Goroutine 的栈空间初始很小(通常为 2KB),可以轻松创建成千上万的 Goroutine。
  • 动态扩展:Goroutine 的栈空间会根据需要动态扩展和收缩。
2. Channel

Channel 是 Goroutine 之间的通信机制,用于传递数据。其特点包括:

  • 类型安全:Channel 有明确的类型,只能传递指定类型的数据。
  • 同步通信:发送和接收操作是阻塞的,确保数据的同步传递。
  • 双向或单向:Channel 可以是双向的,也可以是单向的(只发送或只接收)。

GPM 调度模型

Golang 的并发调度由 GPM 模型 实现,即:

  • G(Goroutine):用户级的轻量级线程,每个 Goroutine 保存自己的上下文信息。
  • P(Processor):逻辑处理器,负责调度 Goroutine 和线程(M)之间的关联关系。
  • M(Machine):操作系统线程,负责执行 Goroutine。
GPM 的工作原理
  1. 初始化:Go 程序启动时,会创建多个 P(默认等于 CPU 核心数),每个 P 绑定一个 M。
  2. Goroutine 调度
    • 每个 P 维护一个本地 Goroutine 队列(Local Runqueue)。
    • 当一个 Goroutine 被创建时,会被放入某个 P 的本地队列中。
    • M 从绑定的 P 的本地队列中获取 Goroutine 并执行。
  3. 阻塞处理
    • 如果 Goroutine 发生阻塞(如 IO 操作),M 会释放 P,P 会绑定到另一个 M 继续执行其他 Goroutine。
    • 当阻塞的 Goroutine 恢复时,会被放入全局队列(Global Runqueue)或某个 P 的本地队列中。
  4. 负载均衡
    • 如果某个 P 的本地队列为空,它会从全局队列或其他 P 的本地队列中“偷取” Goroutine。
    • 如果全局队列也为空,M 会进入休眠状态,直到有新的 Goroutine 被创建。

GPM 调度模型
G Goroutine
P Processor
M Machine
用户级轻量级线程
保存上下文信息
逻辑处理器
调度 Goroutine 和 M 的关系
操作系统线程
执行 Goroutine
维护本地 Goroutine 队列
从队列中获取 Goroutine
执行 Goroutine
是否阻塞?
释放 PM 绑定到其他 P
继续执行
阻塞恢复后放入全局队列
其他 P 从全局队列中偷取 Goroutine
以下是 Golang 中使用 Goroutine 和 Channel 实现并发通信的示例:
package mainimport ("fmt""time"
)func worker(id int, jobs <-chan int, results chan<- int) {for job := range jobs {fmt.Printf("Worker %d started job %d\n", id, job)time.Sleep(time.Second) // 模拟任务执行fmt.Printf("Worker %d finished job %d\n", id, job)results <- job * 2 // 将结果发送到 results Channel}
}func main() {const numJobs = 5jobs := make(chan int, numJobs)results := make(chan int, numJobs)// 启动 3 个 Worker Goroutinefor w := 1; w <= 3; w++ {go worker(w, jobs, results)}// 发送任务到 jobs Channelfor j := 1; j <= numJobs; j++ {jobs <- j}close(jobs)// 从 results Channel 中接收结果for a := 1; a <= numJobs; a++ {fmt.Println("Result:", <-results)}
}

相关文章:

Golang并发机制及CSP并发模型

Golang 并发机制及 CSP 并发模型 Golang 是一门为并发而生的语言&#xff0c;其并发机制基于 CSP&#xff08;Communicating Sequential Processes&#xff0c;通信顺序过程&#xff09; 模型。CSP 是一种描述并发系统中交互模式的正式语言&#xff0c;强调通过通信来共享内存…...

HTML 文本格式化详解

在网页开发中&#xff0c;文本内容的呈现方式直接影响用户的阅读体验。HTML 提供了多种文本格式化元素&#xff0c;可以帮助我们更好地控制文本的显示效果。本文将详细介绍 HTML 中的文本格式化元素及其使用方法&#xff0c;帮助你轻松实现网页文本的美化。 什么是 HTML 文本格…...

我谈《概率论与数理统计》的知识体系

学习《概率论与数理统计》二十多年后&#xff0c;在廖老师的指导下&#xff0c;才厘清了各章之间的关系。首先&#xff0c;这是两个学科综合的一门课程&#xff0c;这一门课程中还有术语冲突的问题。这一门课程一条线两个分支&#xff0c;脉络很清晰。 概率论与统计学 概率论…...

五、华为 RSTP

RSTP&#xff08;Rapid Spanning Tree Protocol&#xff0c;快速生成树协议&#xff09;是 STP 的优化版本&#xff0c;能实现网络拓扑的快速收敛。 一、RSTP 原理 快速收敛机制&#xff1a;RSTP 通过引入边缘端口、P/A&#xff08;Proposal/Agreement&#xff09;机制等&…...

基于Java Web的网上房屋租售网站

内容摘要 本毕业设计题目为《基于Java Web的网上房屋租售网站》&#xff0c;是在信息化时代下充分利用互联网对传统房屋租售方式进行创新&#xff0c;在互联网上进行房屋租售突破了传统方式的局限性。对于房屋租售的当事人都提供了极大的便利。本稳针对了实际用户需求&#xf…...

Pyside6(PyQT5)中的QTableView与QSqlQueryModel、QSqlTableModel的联合使用

QTableView 是QT的一个强大的表视图部件&#xff0c;可以与模型结合使用以显示和编辑数据。QSqlQueryModel、QSqlTableModel 都是用于与 SQL 数据库交互的模型,将二者与QTableView结合使用可以轻松地展示和编辑数据库的数据。 QSqlQueryModel的简单应用 import sys from PySid…...

git常用命令学习

目录 文章目录 目录第一章 git简介1.Git 与SVN2.Git 工作区、暂存区和版本库 第二章 git常用命令学习1.ssh设置2.设置用户信息3.常用命令设置1.初始化本地仓库init2.克隆clone3.查看状态 git status4.添加add命令5.添加评论6.分支操作1.创建分支2.查看分支3.切换分支4.删除分支…...

【优选算法】7----三数之和

来了来了&#xff0c;他来了&#xff0c;又是学习算法的一天~ 今天的嘉宾是中等难度的算法题----三数之和&#xff01; ------------------------------------------begin------------------------------------ 题目解析&#xff1a; 哇趣&#xff01;又是给了一个数组&#…...

分子动力学模拟里的术语:leap-frog蛙跳算法和‌Velocity-Verlet算法

分子动力学模拟&#xff08;Molecular Dynamics Simulation&#xff0c;简称MD&#xff09;是一种基于经典力学原理的计算物理方法&#xff0c;用于模拟原子和分子在给定时间内的运动和相互作用‌。以下是关于分子动力学模拟的一些核心术语和概念&#xff1a; ‌定义系统‌&am…...

2025年数学建模美赛:A题分析(1)Testing Time: The Constant Wear On Stairs

2025年数学建模美赛 A题分析&#xff08;1&#xff09;Testing Time: The Constant Wear On Stairs 2025年数学建模美赛 A题分析&#xff08;2&#xff09;楼梯磨损分析模型 2025年数学建模美赛 A题分析&#xff08;3&#xff09;楼梯使用方向偏好模型 2025年数学建模美赛 A题分…...

利用 SoybeanAdmin 实现前后端分离的企业级管理系统

引言 随着前后端分离架构的普及&#xff0c;越来越多的企业级应用开始采用这种方式来开发。前后端分离不仅提升了开发效率&#xff0c;还让前端和后端开发可以并行进行&#xff0c;减少了相互之间的耦合度。SoybeanAdmin 是一款基于 Spring Boot 和 MyBatis-Plus 的后台管理系…...

996引擎 - 前期准备-配置开发环境

996引擎 - 前期准备 官网搭建服务端、客户端单机搭建 开发环境配置后端开发环境配置环境 前端开发环境配置环境 后端简介前端简介GUILayoutGUIExport 官网 996传奇引擎官网 所有资料从官网首页开始&#xff0c;多探索。 文档&#xff1a; 996M2-服务端Lua 996M2-客户端Lua 搭…...

Tensor 基本操作4 理解 indexing,加减乘除和 broadcasting 运算 | PyTorch 深度学习实战

前一篇文章&#xff0c;Tensor 基本操作3 理解 shape, stride, storage, view&#xff0c;is_contiguous 和 reshape 操作 | PyTorch 深度学习实战 本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started Tensor 基本使用 索引 indexing示例代码 加减…...

【Uniapp-Vue3】request各种不同类型的参数详解

一、参数携带 我们调用该接口的时候需要传入type参数。 第一种 路径名称?参数名1参数值1&参数名2参数值2 第二种 uni.request({ url:"请求路径", data:{ 参数名:参数值 } }) 二、请求方式 常用的有get&#xff0c;post和put 三种&#xff0c;默认是get请求。…...

【Prometheus】Prometheus如何监控Haproxy

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…...

SSM开发(一)JAVA,javaEE,spring,springmvc,springboot,SSM,SSH等几个概念区别

目录 JAVA 框架 javaEE spring springmvc springboot SSM SSH maven JAVA 一种面向对象、高级编程语言&#xff0c;Python也是高级编程语言&#xff1b;不是框架(框架&#xff1a;一般用于大型复杂需求项目&#xff0c;用于快速开发)具有三大特性&#xff0c;所谓Jav…...

HTML5 常用事件详解

在现代 Web 开发中&#xff0c;用户交互是提升用户体验的关键。HTML5 提供了丰富的事件机制&#xff0c;允许开发者监听用户的操作&#xff08;如点击、拖动、键盘输入等&#xff09;&#xff0c;并触发相应的逻辑处理。本文将详细介绍 HTML5 中的常用事件&#xff0c;包括鼠标…...

TCP全连接队列

1. 理解 int listen(int sockfd, int backlog) 第二个参数的作用 backlog&#xff1a;表示tcp全连接队列的连接个数1。 如果连接个数等于backlog1&#xff0c;后续连接就会失败&#xff0c;假设tcp连接个数为0&#xff0c;最大连接个数就为1&#xff0c;并且不accept获取连接…...

统计文本文件中单词频率的 Swift 与 Bash 实现详解

网罗开发 &#xff08;小红书、快手、视频号同名&#xff09; 大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等…...

iOS 权限管理:同时请求相机和麦克风权限的最佳实践

引言 在开发视频类应用时&#xff0c;我们常常会遇到需要同时请求相机和麦克风权限的场景。比如&#xff0c;在用户发布视频动态时&#xff0c;相机用于捕捉画面&#xff0c;麦克风用于录制声音&#xff1b;又或者在直播功能中&#xff0c;只有获得这两项权限&#xff0c;用户…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

HTML前端开发:JavaScript 获取元素方法详解

作为前端开发者&#xff0c;高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法&#xff0c;分为两大系列&#xff1a; 一、getElementBy... 系列 传统方法&#xff0c;直接通过 DOM 接口访问&#xff0c;返回动态集合&#xff08;元素变化会实时更新&#xff09;。…...

【UE5 C++】通过文件对话框获取选择文件的路径

目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 &#xff0c;这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器&#xff0c;右键点击 .uproject 文件&#xff0c;选择 "Generate Visual Studio project files"&#xff0c;重…...

【WebSocket】SpringBoot项目中使用WebSocket

1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖&#xff0c;添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...

QT开发技术【ffmpeg + QAudioOutput】音乐播放器

一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下&#xff0c;音视频内容犹如璀璨繁星&#xff0c;点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频&#xff0c;到在线课堂中知识渊博的专家授课&#xff0c;再到影视平台上扣人心弦的高清大片&#xff0c;音…...

C++--string的模拟实现

一,引言 string的模拟实现是只对string对象中给的主要功能经行模拟实现&#xff0c;其目的是加强对string的底层了解&#xff0c;以便于在以后的学习或者工作中更加熟练的使用string。本文中的代码仅供参考并不唯一。 二,默认成员函数 string主要有三个成员变量&#xff0c;…...

goreplay

1.github地址 https://github.com/buger/goreplay 2.简单介绍 GoReplay 是一个开源的网络监控工具&#xff0c;可以记录用户的实时流量并将其用于镜像、负载测试、监控和详细分析。 3.出现背景 随着应用程序的增长&#xff0c;测试它所需的工作量也会呈指数级增长。GoRepl…...