Go 为什么不能在第一个存储之后复制原子值?

Go 为什么不能在第一个存储之后复制原子值?,go,concurrency,atomic,Go,Concurrency,Atomic,值提供一致类型值的原子加载和存储。值的零值从Load返回nil。调用存储后,不得复制值 我从atomic.Value上读到了上面的评论。 它说“不得复制值”,但没有说明原因 为什么不能在第一个存储之后复制原子值 为什么不能在第一个存储之后复制原子值 因为文件上是这么说的 (内部实现需要这一点。这里没有什么可看的,关于这一点没有可操作的东西。)除了@Volker的回答和@icza的评论外,推理非常简单:原子值的实现包括一些用于提供类型的契约所保证的原子性的东西,直接-与包含对此类对象的引用或(通常

值提供一致类型值的原子加载和存储。值的零值从Load返回nil。调用存储后,不得复制值

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

为什么不能在第一个存储之后复制原子值

为什么不能在第一个存储之后复制原子值

因为文件上是这么说的


(内部实现需要这一点。这里没有什么可看的,关于这一点没有可操作的东西。)

除了@Volker的回答和@icza的评论外,推理非常简单:
原子值的实现包括一些用于提供类型的契约所保证的原子性的东西,直接-与包含对此类对象的引用或(通常情况下)指向此类对象的指针相反,因此当将类型为
atomic.Value
的变量复制到另一个变量时,“对象”也会被复制(克隆)

现在假设一个实现决定在
atomic.Value
a(通常是内核提供的)类型中包含一个或任何其他方便的锁定机制

现在考虑一个争用的例子:一些goroutine试图读取值,而另一个goroutine试图并行地修改它。 写入goroutine通过该内部保护机制“获得”独占写入权限(不管它是如何实现的),然后您复制该值。 撇开这种复制创建经典数据竞争案例的问题不谈,您现在可以看到复制的结果将是两个类型为
atomic.Value
的变量,并且每个变量都将被“锁定”以获得独占写入权限。 但是,虽然原始变量仍处于可感知状态,但希望更新变量的goroutine最终将完成该操作,并将“释放”其许可证,使变量返回正常状态,副本将永远锁定在“获取以进行更新”中在没有goroutine打算执行该更新时进行状态。哎呀



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

因为如果您复制它,它将无法提供它的用途。为什么?这就是它的实现方式,这是一个实现细节。