【go从零单排】Stateful Goroutines(有状态的 goroutines)

devtools/2024/11/14 13:11:59/

挪威特罗姆瑟夜景

🌈Don’t worry , just coding!
内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。

📗概念

在 Go 中,有状态的 goroutines(Stateful Goroutines)是指那些能够保留状态信息的 goroutines。这种设计模式通常用于需要在多个调用之间维护状态的场景,例如处理请求、管理连接、维护计数器等。

💻代码

package main//导入math/rand 用于生成随机数。
//sync/atomic 提供原子操作的支持。
import ("fmt""math/rand""sync/atomic""time"
)// readOp 结构体用于表示读操作,包含一个键 key 和一个响应通道 resp。
type readOp struct {key  intresp chan int
}// readOp 结构体用于表示读操作,包含一个键 key 和一个响应通道 resp。
type writeOp struct {key  intval  intresp chan bool
}func main() {//声明两个无符号整型变量 readOps 和 writeOps,用于计数读写操作。var readOps uint64var writeOps uint64//创建两个通道 reads 和 writes,分别用于接收读操作和写操作。reads := make(chan readOp)writes := make(chan writeOp)go func() {//启动一个 goroutine,维护一个状态 state,这是一个映射,存储键值对。var state = make(map[int]int)for {//使用 select 语句监听 reads 和 writes 通道:select {//如果接收到读操作,从 state 中读取对应的值并通过 resp 通道返回。case read := <-reads:read.resp <- state[read.key]//如果接收到写操作,将值写入 state 中,并通过 resp 通道返回操作成功的信号。case write := <-writes:state[write.key] = write.valwrite.resp <- true}}}()//启动 100 个 goroutinefor r := 0; r < 100; r++ {go func() {for {//创建一个随机键的 readOp 实例并发送到 reads 通道。read := readOp{key:  rand.Intn(5),resp: make(chan int)}reads <- read<-read.resp//创建一个随机键的 readOp 实例并发送到 reads 通道。atomic.AddUint64(&readOps, 1)//每次循环后休眠 1 毫秒。time.Sleep(time.Millisecond)}}()}//启动 10 个 goroutinefor w := 0; w < 10; w++ {go func() {for {//创建一个随机键和随机值的 writeOp 实例并发送到 writes 通道。write := writeOp{key:  rand.Intn(5),val:  rand.Intn(100),resp: make(chan bool)}writes <- write<-write.resp//等待响应并通过原子操作增加 writeOps 的计数。atomic.AddUint64(&writeOps, 1)//每次循环后休眠 1 毫秒。time.Sleep(time.Millisecond)}}()}time.Sleep(time.Second)//使用 atomic.LoadUint64 获取最终的读写操作计数并打印。readOpsFinal := atomic.LoadUint64(&readOps)fmt.Println("readOps:", readOpsFinal)writeOpsFinal := atomic.LoadUint64(&writeOps)fmt.Println("writeOps:", writeOpsFinal)
}
//输出
//readOps: 81299
//writeOps: 8163

有状态的 Goroutines 的特点

  • 状态管理:有状态的 goroutines 可以在其生命周期内维护状态信息,这样它们可以根据之前的操作或输入做出决策。
  • 并发安全:在并发环境中,状态的管理需要确保安全性,通常使用通道、互斥锁或其他同步机制来保护共享状态。
  • 封装性:将状态和行为封装在 goroutine 内部,使得外部无法直接访问状态,从而增强了模块化和封装性。

🔍理解

  • 并发读写:代码实现了一个简单的并发读写操作,使用通道来协调读写请求。
  • 原子操作:使用 sync/atomic 包中的原子操作来安全地更新读写计数,避免数据竞争。
  • 随机访问:读和写操作都是基于随机生成的键值,使得操作更加多样化。
  • 无锁设计:通过通道和 goroutine 的组合,避免了传统的锁机制,简化了并发控制。

💪无人扶我青云志,我自踏雪至山巅。
在这里插入图片描述


http://www.ppmy.cn/devtools/133617.html

相关文章

基于ECS实例搭建Hadoop环境

环境搭建&#xff1a; 【ECS生长万物之开源】基于ECS实例搭建Hadoop环境-阿里云开发者社区 搭建Hadoop环境_云服务器 ECS(ECS)-阿里云帮助中心 Hadoop入门基础&#xff08;二&#xff09;&#xff1a;Hadoop集群安装与部署详解&#xff08;超详细教程&#xff09;&#xff0…

什么是 DAPP?它能解决什么问题?

在区块链技术日益火热的今天&#xff0c;DAPP 这个概念也逐渐走入人们的视野。但是很多人都听到了DAPP这个词&#xff0c;但是大部分人却还是不清楚什么是 DAPP&#xff1f;它又能解决什么问题呢&#xff1f;接下来这篇文章就带大家了解一下DAPP。 一、什么是 DAPP&#xff1f…

计算机课程管理:Spring Boot与工程认证的协同创新

3系统分析 3.1可行性分析 通过对本基于工程教育认证的计算机课程管理平台实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本基于工程教育认证的计算机课程管理平…

SpringBoot操作Elasticsearch

SpringBoot操作Elasticsearch SpringData框架简化Java代码连接ES的过程 官网&#xff1a;https://spring.io/projects/spring-data/ 以上列表中都是Spring Data支持连接的数据源 添加依赖 已经添加过了 <!--添加SpringDataES的依赖--><dependency><groupId&…

【Python进阶】Python中的数据库交互:使用SQLite进行本地数据存储

1、数据持久化与访问效率 数据持久化是指程序运行过程中产生的数据能够长期保存&#xff0c;即使程序关闭或系统重启后仍可读取和修改。通过数据库&#xff0c;我们可以确保数据持久化的同时&#xff0c;实现数据的快速访问。例如&#xff0c;银行系统需要实时更新账户余额&am…

js三大组成部分

一&#xff0c;js三大组成部分 &#xff08;一&#xff09;组成部分&#xff1a; &#xff08;1&#xff09;ECMAScript:代表了语言的标准&#xff0c;规范&#xff0c;描述了语言的基本语法和数据类型。 &#xff08;2&#xff09;BOM:代表了浏览器。 <1>描述了浏览器的…

C/C++基础知识复习(15)

1) new 和 malloc 的区别及用法 区别&#xff1a; 类型安全&#xff1a;new 是 C 运算符&#xff0c;它会调用对象的构造函数并返回正确类型的指针&#xff1b;malloc 是 C 的函数&#xff0c;它返回的是 void*&#xff0c;需要显式转换为目标类型。初始化&#xff1a;new 在…

计算机网络——1.2计算机网络的组成

计算机网络——计算机网络的组成 前言 上一节&#xff0c;我们学习了计算机网络的基本概念&#xff0c;接下来我们来了解下计算机网络是由哪些部分组成的。 计算机网络的组成 计算机网络的组成按照不同的分类逻辑&#xff0c;组成部分也有着些许差别。 从组成部分上看 硬件 …