當我研究 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條經驗 獲得超5個贊
來自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 關注
- 109 瀏覽
添加回答
舉報
0/150
提交
取消
