Golang的copyCheck.check如何检测对象复制?

问题描述 投票:2回答:2

golang的copyCheck.check如何检测对象复制?

// copyChecker holds back pointer to itself to detect object copying.
type copyChecker uintptr

func (c *copyChecker) check() {
    if uintptr(*c) != uintptr(unsafe.Pointer(c)) &&
        !atomic.CompareAndSwapUintptr((*uintptr)(c), 0, uintptr(unsafe.Pointer(c))) &&
        uintptr(*c) != uintptr(unsafe.Pointer(c)) {
        panic("sync.Cond is copied")
    }
}
go
2个回答
1
投票

创建它时,它将其值设置为自己的地址。要检查它是否已被复制,它会将其地址与存储的值进行比较。如果它被复制,它的地址将不同,但值将相同,因此它将不再指向自身。


1
投票

好的,首先看看copyChecker是什么:它是一个uintptr。因此,有一个关键点:声称在首次使用后不得复制该物品。每个“use”(导出的方法)都从调用对象的checker开始。第一次调用Cond类型的方法之一时,它会隐藏其checker的地址。将来的任何使用都将检查检查器对象是否在存储的地址。如果你复制它,副本将必须有一个不同的地址,这将是恐慌。

实际检查的工作原理:

第一次被击中时,c为零,所以它与c实际上的地址不同。有一个原子交换,当且仅当当前值为零时才在c的地址交换,并确保这种情况以原子方式发生。如果c为零或c的值不是自己的地址,则第一次比较可以成功。比较确保它不为零。因此,当第三次比较发生时,该值为零并且此后已设置为其当前地址(并且它们不会不相等),或者该值首先不为零。如果该值不为零,并且也与当前地址不同,则表示此Cond是通过获取已使用的Cond并将其复制到新地址而制作的。

© www.soinside.com 2019 - 2024. All rights reserved.