int64的读写操作是否具有原子性质
Posted adream307
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了int64的读写操作是否具有原子性质相关的知识,希望对你有一定的参考价值。
在 x86-64
机器上,int64
的读写操作是否具有原子性?
假设变量 val
是 int64
, 现在有两个线程,线程 writer
只负责向 val
写入数据,线程 reader
只负从 val
读取数据
假设 val
当前值为 0x0102030405060708
writer
线程正在执行写操作,将数据 0x0000111100002222
写入 val
reader
线程正在执行读操作,从 val
读取数据
那么 reader
线程得到的 val
只能是 0x0102030405060708
或 0x0000111100002222
还是某个不确定的中间状态?
如果 int64
的读写操作具有原子性,那么 reader
线程得到的只能是 0x0102030405060708
或 0x0000111100002222
如果 int64
的读写操作不具有原子性,那么 reader
线程得到可能是中间某个不确定的状态,比如前一半是 writer
正在写入的数据,后一半是旧的数据 0x0000111105060708
测试程序如下:
- 写入
val
的值一定是符合奇偶校验的 - 开启
10
个线程同时向val
输入数据 - 读线程连续的从
val
读取数据,并检查是否符合奇偶校验 - 如果
int64
的读写操作具备原子性,读线程得到的数据一定是符合奇偶校验的
测试发现,在 x86 64
机器上, int64
的读写操作确实具备原子性
package main
import (
"log"
"math/rand"
"sync"
)
func check(v int64) bool
var num int = 0
for i := 0; i < 64; i++
if v&0x01 != 0
num++
v = v >> 1
return num%2 == 0
func write(p *int64)
v := rand.Int63()
if check(v)
v = v ^ 0x01
*p = v
func main()
var wg sync.WaitGroup
var val int64
write(&val)
for i := 0; i < 10; i++
wg.Add(1)
go func()
defer wg.Done()
for i := 0; i < 10000000; i++
write(&val)
()
go func()
for
v := val
if check(v)
log.Fatalf("atomic test faile, val = %d", v)
()
wg.Wait()
log.Printf("test finished")
以上是关于int64的读写操作是否具有原子性质的主要内容,如果未能解决你的问题,请参考以下文章
我可以将 std::atomic<int64> 放在共享内存中并期望原子操作吗?