GO的多协程程序,多个CPU执行,共享数据出现不一致的问题

首先,先看看这一段代码

var x, y int
func main()  {
	go func() {
		x = 1
		fmt.Println("y = ", y)
	}()
	go func() {
		y = 1
		fmt.Println("x = ", x)
	}()
	time.Sleep(time.Second)
}

打印的结果又很多种

y = 0 x = 1

x = 0 y = 1

x = 1 y = 1

y = 1 x = 1

但是还有一种结果是: x = 0 y = 0,虽然你执行的时候可能不会出现这种情况,但是他确实是存在的

出现这种结果的可能有两个原因:

一,

因为赋值和打印的变量不是同一个,所以编译器就可能会认为两条语句的执行顺序不会影响结果,然后就交换了这两个语句的执行顺序

二,

两个协程可能在不同的CPU上运行,假设第一个协程在CPU1上运行,第二个协程在CPU2上运行,但是由于每个CPU都会缓存,只有在必要的时候才会写入主内存,其他的CPU才能看到。

CPU1对 x 进行了修改,但是它只是在自己的本地缓存进行了修改,并没有写入到主内存,所以CPU2看不到,它就打印它上次从主内存取得的过期值。同理CPU1也是打印了 y 的过期值。所以就会出现 x和y同时等于零的情况

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在Go语言中,多协程执行的顺序并不是固定的,每一次运行的结果都可能不同。通常情况下,我们无法确定哪个协程会先执行完毕。 然而,如果我们需要确保所有的协程执行完毕之后才能进行下一步的操作,我们可以使用WaitGroup来实现这个目的。WaitGroup是Go语言的一个同步原语,它可以用来等待一组协程的完成。 在使用WaitGroup时,我们需要在主协程中创建一个WaitGroup对象,并设置需要等待的协程数量。然后,在每个协程的最后调用Done()方法,表示该协程已经执行完毕。最后,我们在主协程中调用Wait()方法,这会导致主协程在所有协程执行完毕之前一直等待。 下面是一个使用WaitGroup的例子: ```go package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup // 设置需要等待的协程数量 wg.Add(2) // 第一个协程 go func() { defer wg.Done() // 协程执行的任务 fmt.Println("协程1执行完毕") }() // 第二个协程 go func() { defer wg.Done() // 协程执行的任务 fmt.Println("协程2执行完毕") }() // 等待所有协程执行完毕 wg.Wait() // 所有协程执行完毕后才会执行下面的代码 fmt.Println("所有协程执行完毕") } ``` 在上述代码中,我们创建了一个WaitGroup对象`wg`,然后通过`wg.Add(2)`告诉它有两个协程需要等待。在每个协程的最后,我们都调用了`wg.Done()`表示该协程已经执行完毕。最后,我们通过`wg.Wait()`使主协程等待所有协程执行完毕。 这样,当所有的协程执行完毕之后,主协程才会执行下面的代码。这样就保证了所有协程执行完毕之后才执行
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值