当我研究 sync.WaitGroup 中的代码时,我注意到 WaitGroup 使用 state1([3]uint32) 字段来假设状态原子存储的 64 位对齐指针。像这样:// https://github.com/golang/go/issues/19149type WaitGroup struct { noCopy noCopy state1 [3]uint32}// state returns pointers to the state and sema fields stored within wg.state1.func (wg *WaitGroup) state() (statep *uint64, semap *uint32) { if uintptr(unsafe.Pointer(&wg.state1))%8 == 0 { return (*uint64)(unsafe.Pointer(&wg.state1)), &wg.state1[2] } else { return (*uint64)(unsafe.Pointer(&wg.state1[1])), &wg.state1[0] }}但是当我在 mac 和 linux 上检查时,在 64 位系统上,第一个分配的 4 字节对齐数据结构地址显示在 mod 8 之后是4,而在 32 位系统上它是0。我很好奇它在golang中是如何保证的?代码在这里: https: //play.golang.org/p/oiZMHd2c0I6// 32-bit system:// GOARCH=386 go run main.go// 0 4 0 //why first address mod 8 is 0// 64-bit system:// go run main.go// 4 0 4 //why first address mod 8 is 4更新:使用@Renat 的答案地址,不能保证变量地址。输出可能不包含。
1 回答
收到一只叮咚
TA贡献1821条经验 获得超4个赞
来自golang.org:
计算机架构可能需要对齐内存地址;也就是说,对于一个变量的地址是一个因子的倍数,变量的类型的对齐。函数 Alignof 接受一个表示任何类型变量的表达式,并以字节为单位返回变量(类型)的对齐方式。
Alignof(c)因此,鉴于4,它将与 对齐4,而不是与8字节对齐。
当创建另一个对象时M
var c = M{}
var d = M{}
println(
unsafe.Sizeof(c),
unsafe.Alignof(c),
uintptr(unsafe.Pointer(&c.x))%8,
)
println(
" ",
uintptr(unsafe.Pointer(&d.x))%8,
)
我有:
12 4 4
0
- 1 回答
- 0 关注
- 80 浏览
添加回答
举报
0/150
提交
取消