golang并发写入具有相同值的uint64变量?
golang concurrent write to uint64 variable with same values?
type simpleTx struct {
gas uint64
}
func (tx *simpleTx) UpdateGas() {
tx.gas = 125
}
func TestUpdateGas(t *testing.T) {
var wg sync.WaitGroup
wg.Add(100)
tx := &simpleTx{}
for i:=0; i <100; i++ {
go func(t *simpleTx)() {
tx.UpdateGas()
wg.Done()
}(tx)
}
wg.Wait()
}
上面的测试在 运行 和 -race
选项时打印出“WARNING:DATA RACE”。
golang 中是否有任何类型可用于具有相同值的并发写入?
我是否需要始终使用互斥量或原子变量?
是的,有许多 Go 习语可以使用 - 以防止数据竞争 - 不应该在没有适当同步的情况下并发写入变量(或并发读写):
- 对于您的特殊情况 - 写入相同的值。使用
sync.Once
:
type simpleTx struct {
sync.Once
gas uint64
}
func (tx *simpleTx) UpdateGas() {
tx.Do(func() { tx.gas = 125 })
}
- 使用
atomic.StoreUint64
进行原子写入:
atomic.StoreUint64(&tx.gas, 125)
- 使用
sync.Mutex
:
type simpleTx struct {
sync.Mutex
gas uint64
}
func (tx *simpleTx) UpdateGas() {
tx.Lock()
tx.gas = 125
tx.Unlock()
}
- 使用频道:
type simpleTx struct {
gas chan uint64
}
func (tx *simpleTx) UpdateGas() {
select {
case tx.gas <- 125:
default:
}
}
func TestUpdateGas(t *testing.T) {
var wg sync.WaitGroup
tx := &simpleTx{make(chan uint64, 1)}
for i := 0; i < 100; i++ {
wg.Add(1)
go func(t *simpleTx) {
tx.UpdateGas()
wg.Done()
}(tx)
}
wg.Wait()
}
type simpleTx struct {
gas uint64
}
func (tx *simpleTx) UpdateGas() {
tx.gas = 125
}
func TestUpdateGas(t *testing.T) {
var wg sync.WaitGroup
wg.Add(100)
tx := &simpleTx{}
for i:=0; i <100; i++ {
go func(t *simpleTx)() {
tx.UpdateGas()
wg.Done()
}(tx)
}
wg.Wait()
}
上面的测试在 运行 和 -race
选项时打印出“WARNING:DATA RACE”。
golang 中是否有任何类型可用于具有相同值的并发写入?
我是否需要始终使用互斥量或原子变量?
是的,有许多 Go 习语可以使用 - 以防止数据竞争 - 不应该在没有适当同步的情况下并发写入变量(或并发读写):
- 对于您的特殊情况 - 写入相同的值。使用
sync.Once
:
type simpleTx struct {
sync.Once
gas uint64
}
func (tx *simpleTx) UpdateGas() {
tx.Do(func() { tx.gas = 125 })
}
- 使用
atomic.StoreUint64
进行原子写入:
atomic.StoreUint64(&tx.gas, 125)
- 使用
sync.Mutex
:
type simpleTx struct {
sync.Mutex
gas uint64
}
func (tx *simpleTx) UpdateGas() {
tx.Lock()
tx.gas = 125
tx.Unlock()
}
- 使用频道:
type simpleTx struct {
gas chan uint64
}
func (tx *simpleTx) UpdateGas() {
select {
case tx.gas <- 125:
default:
}
}
func TestUpdateGas(t *testing.T) {
var wg sync.WaitGroup
tx := &simpleTx{make(chan uint64, 1)}
for i := 0; i < 100; i++ {
wg.Add(1)
go func(t *simpleTx) {
tx.UpdateGas()
wg.Done()
}(tx)
}
wg.Wait()
}