golang中的并发竞争态

本文通过具体示例探讨了Golang中并发竞争的问题,解释了为何两个goroutine访问共享资源会引发竞争态,并展示了如何使用原子操作解决此问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

golang程序中并发会引起并发竞争,一起没理解,为什么说两个goroutine访问共享资源会引发竞争态,我的理解如果只使用一个逻辑处理器本质上不就是同一时间只有一个goroutine在跑吗,为什么会引发竞争态呢,做了如下实验,确实存在竞争态

package main

import (
	"fmt"
	"runtime"
	"sync"
	// "sync/atomic"
)

var (
	counter int64
	wg      sync.WaitGroup
)

func main() {
	wg.Add(2)
	go inCounter("A")
	go inCounter("B")
	wg.Wait()
	fmt.Println("Final Counter:", counter)
}
func inCounter(prefix string) {
	defer wg.Done()
	for count := 0; count < 2; count++ {
		// atomic.AddInt64(&counter, 1)
		counter++
        fmt.Println(prefix, " excute Counter:", counter)
		runtime.Gosched()

	}

}

这段程序我多次执行,有一次结果是这样的:

B  excute Counter: 1
B  excute Counter: 2
A  excute Counter: 1
A  excute Counter: 3
Final Counter: 3

这结果完全不正确

所以它的执行顺序可能是这样的

    1.   B  执行完 couter++  这是 couter = 1

    2.  A开始读取couter的值(1)

    3.  B 执行完 couter++  counter ==2 (执行完成)

    4.  A 执行完 couter+1  此时  couter == 2

    5.  A 执行完couter++   此时couter=3

所以本质上是couter++ 存在读取和赋值的过程,就是goroutine A刚读取了couter,将要赋值时,被goroutineB赋值了,这时它的赋值就失去了。  所以它需要加锁,使用原子锁将update couter 整个过程锁住。

package main

import (
	"fmt"
	"runtime"
	"sync"
	"sync/atomic"
)

var (
	counter int64
	wg      sync.WaitGroup
)

func main() {
	wg.Add(2)
	go inCounter("A")
	go inCounter("B")
	wg.Wait()
	fmt.Println("Final Counter:", counter)
}
func inCounter(prefix string) {
	defer wg.Done()
	for count := 0; count < 2; count++ {
		atomic.AddInt64(&counter, 1)
		// counter++
		fmt.Println(prefix, " excute Counter:", counter)
		runtime.Gosched()

	}

}

    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值