gpt4 book ai didi

go - 使用同步/原子包进行同步的代码中的意外行为

转载 作者:行者123 更新时间:2023-12-01 21:17:32 26 4
gpt4 key购买 nike

以下是我在学习Golang中的goroutine时正在处理的示例。在下面的代码中,我们产生了30个goroutine,每个goroutine访问一个称为ordersProcessed的共享变量。该示例表示出纳员处理订单。一旦ordersProcessed超过10,我们将打印出收银员无法再接受任何订单。

package main

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

func main() {
var (
wg sync.WaitGroup
ordersProcessed int64
)
// This does not work as expected
cashier := func(orderNum int) {
value := atomic.LoadInt64(&ordersProcessed)
fmt.Println("Value is ", value)
if value < 10 {
// Cashier is ready to serve!
fmt.Println("Proessing order", orderNum)
atomic.AddInt64(&ordersProcessed, 1)
} else {
// Cashier has reached the max capacity of processing orders.
fmt.Println("I am tired! I want to take rest!", orderNum)
}
wg.Done()
}

for i := 0; i < 30; i++ {
wg.Add(1)
go func(orderNum int) {
// Making an order
cashier(orderNum)
}(i)

}
wg.Wait()
}
我期望看到10个订单的已处理消息,此后无法处理。但是,所有30个订单都得到处理。我使用了sync/atomic包来同步对ordersProcessed变量的访问,但是每个goroutine的值始终都读为0。但是,如果我将上面的代码更改为使用互斥量,如下所示,它将按预期工作:
package main

import (
"fmt"
"sync"
)

func main() {
var (
wg sync.WaitGroup
ordersProcessed int64
mutex sync.Mutex
)
// This works as expected
cashier := func(orderNum int) {
mutex.Lock()
if ordersProcessed < 10 {
// Cashier is ready to serve!
fmt.Println("Processing order", orderNum)
ordersProcessed++
} else {
// Cashier has reached the max capacity of processing orders.
fmt.Println("I am tired! I want to take rest!", orderNum)
}
mutex.Unlock()
wg.Done()
}

for i := 0; i < 30; i++ {
wg.Add(1)
go func(orderNum int) {
// Making an order
cashier(orderNum)
}(i)

}
wg.Wait()
}
有人可以告诉我我使用sync/atomic包同步对ordersProcessed变量的访问的方式有什么问题吗?

最佳答案

您使用了sync/atomic程序包,但没有同步goroutine。
当您启动30个goroutine时,每个goroutine都会通过读取共享变量并将其递增来启动。如果所有goroutine都读取了该变量,则它们都将读为0。这里的问题是,您并没有阻止其他goroutine在一个goroutine对其进行操作时修改该变量。程序运行后,共享变量可以是10到30之间的任何值,具体取决于goroutine的交错方式。
您的第二个实现是正确的,它可以防止其他g​​oroutine在其中一个正在使用它时读取和修改共享变量。

关于go - 使用同步/原子包进行同步的代码中的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62939581/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com