学习并发编程中的同步和状态管理。
full lessons here👇:
https://programmerscareer.com/zh-cn/golang-basic-skill/
由AI生成,可能有错误,仅供参考
Topic: Atomic, Mutexes, Stateful Goroutines
首先,让我们设置上下文,理解这些概念:
1. Atomics:
Atomics 在 Go 中是“sync/atomic”包中的一个部分。它们提供了低级别的锁定机制,用来实现同步。例如,这些原子函数可以帮助在并发安全的情况下添加、比较或加载整数或指针。
2. Mutexes:
Mutex 是“Mutual Exclusion”的缩写。一个 Mutex 就像是一个 token,可以被单个 goroutine 持有。如果其他 goroutines 尝试获取 Mutex,他们将被阻塞,直到当前持有 Mutex 的 goroutine 释放它。这是一个控制访问某段代码的关键工具,这段代码不能安全地并发执行。
3. Stateful Goroutines:
Stateful Goroutines 是保持自己的私有状态的 goroutine。相反,不是通过锁定(像 Atomics 或 Mutexes)来共享变量之间的访问,而是每个 goroutine 负责管理自己的状态,其他 goroutines 通过在通道上发送和接收消息来交互。
让我们看一个例子:
假设我们有多个 goroutines 都想increment 一个计数器。传统的方法是使用 Mutex 来确保安全地访问共享的“counter”变量。
1 | var ( |
现在,让我们看看如何使用 Stateful Goroutines 来实现这个例子:
1 | func main() { |
By using the sync/atomic
package, we ensure that only one goroutine plays with the counter at a time.
Topic: Introduction to Mutexes
Let’s consider a similar situation but with a map:
1 | package main |
This program too has a data race condition. The map
type in Go doesn’t support concurrent reads and writes. A Mutex is used to provide a locking mechanism to ensure that only one Goroutine is running the critical section of code at any point of time to prevent race condition from happening. Mutex is available in the sync
package and provides Lock and Unlock method:
1 | package main |
Now, the sharedRsc
can be safely accessed by multiple goroutines.
主题:使用 Mutex 保护共享状态
在这个部分,我想请你尝试创建一个短程序,使用 mutex 保护共享状态。这可能是一个计数器或任何其他变量,可能会受到数据竞争条件的影响。这个练习应该帮助巩固你的理解关于 mutex。
注意,这些是 Atomics、Mutexes 和 Go 并发编程的基本概念。我们很快就会涉及到高级方面。
让我们继续一步,探索 状态式 Goroutines。
主题:了解状态式 Goroutines
正如我之前轻微地触摸过的那样,状态式 Goroutines 是一种不同的方法来处理共享状态在并发代码中。这个想法是将状态封装在一个 Goroutine 中,并且只通过通信通道暴露对该状态的操作。
这个方法可以使得你的代码更容易理解,因为一致的状态只有在单个、良好定义的位置被改变。
以下是一个示例:
1 | package main |
案例研究 1:使用 Mutex 保护共享状态
考虑你有一个缓存,用于存储键值对,你已经使用 Go 的 map:
1 | type Cache struct { |
案例研究 2:使用 Mutex 和 Map 实现缓存
在这个案例中,你使用一个 map 存储键值对,并且使用 Mutex 保护该缓存。
回顾和评估
为了巩固你的理解,让我们回顾一下主要的概念:
- 原子变量:Go 的
sync/atomic
包提供了低级别的原子内存基本操作,可以用于实现同步算法和数据结构在多线程环境中。 - Mutex:一个 Mutex 是一种互斥 primitive,可以用于保护共享资源免受并发访问。
- 状态式 Goroutines:Goroutines 具有状态,封装在它们自身中,只暴露对该状态的操作通过通信通道。
现在,让我们将你的理解付诸实践。如果你能,请口头走我通过以下场景:
假设你需要开发一个服务器应用程序,它从多个客户端同时接收数字输入,并且维护一个累加总和。概念上,你将使用哪些 Go 并发机制来确保累加总和始终准确,尽管有多个客户端输入?
English post: https://programmerscareer.com/go-basic-06/
作者:Wesley Wei – Twitter Wesley Wei – Medium
注意:本文为作者原创,转载请注明出处。
评论