go - 为什么atomic.Value不能在第一个Store之后复制?

标签 go concurrency atomic

A Value provides an atomic load and store of a consistently typed value. The zero value for a Value returns nil from Load. Once Store has been called, a Value must not be copied.

我从atomic.Value 读到了上述评论。 它说“不得复制值”,但没有说明原因。

为什么atomic.Value不能在第一个Store之后复制?

最佳答案

除了@Volker的回答和@icza的评论之外,推理非常简单:atomic.Value的实现包括something,它用于直接提供由类型契约保证的原子性——而不是包含对此类事物的引用或通常发生的指针,因此当 atomic.Value 类型的变量是复制到另一个变量,“事物”也被复制,(克隆)。

现在假设一个实现决定将一个(通常由内核提供)semaphore 包含到atomic.Value 类型中。或mutex ,或critical section或其他任何东西 - 任何方便的锁定机制。

现在考虑一种争用情况:一些 goroutine 尝试读取该值,而另一个 goroutine 尝试并行修改它。 写入 goroutine 通过该内部保护机制“获取”“独占写入权限”(无论它是如何实现的),然后复制该值。 撇开这种复制创建经典数据竞争案例的问题不谈,您现在可以看到复制的结果将是两个类型为atomic.Value的变量,并且每个其中一些将被“锁定”以获取独占写入权限。 但是,虽然原始变量仍处于合理状态 - 想要更新变量的 Goroutine 最终将完成此操作,并将“释放”其许可,将变量返回到正常状态,但副本将永远锁定在该状态中“已获取更新”状态,而没有 goroutine 打算执行该更新。 糟糕!


顺便说一句,由于完全相同的原因,您无法在第一次使用 sync.Mutex 变量后复制它。

关于go - 为什么atomic.Value不能在第一个Store之后复制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67632767/

相关文章:

c++ - 我必须对 "exit"bool 变量使用 atomic<bool> 吗?

c - 在拥有带有信号处理程序的多线程程序时,有没有办法确保原子性?

silverlight - Dispatcher.BeginInvoke lambda 捕获线程安全?

java - CyclicBarrier:导致屏障跳闸的 'x' 个线程中的 'y' 完成执行并终止

concurrency - OpenCL与Grand Central Dispatch中的并发编程

c++ - 为什么 Boost 原子使用中的多生产者队列是无等待的

go - Go 中有 uint64 字面量吗?

mongodb - Bson接口(interface)有一些问题

golang 使用 gorilla/mux 生成 rest api 文档

go - func 关键字后的两个函数名称 - 它是什么?