gpt4 book ai didi

multithreading - 等待共享计时器的多个 go 例程导致竞争

转载 作者:IT王子 更新时间:2023-10-29 02:05:22 27 4
gpt4 key购买 nike

我需要在多个 go 例程中更新共享对象的计时器。但它最终会出现竞争条件。我不能使用锁来等待 channel ,因为所有其他例程都必须等待。

package main
import(
"time"
"math/rand"
)
type R struct {
timer *time.Timer
//other fields
}

func f(done chan bool,r *R){
r.timer =time.NewTimer(time.Millisecond * time.Duration(1000 + rand.Intn(2)))
//some code simultaneously accessing other fields of shared object r, cannot put a lock here
<-r.timer.C

done <- true
}

func main(){
done := make(chan bool , 5)
var r *R
var t *time.Timer
r = &R{timer:t}
for i:=0;i<5;i++{
go f(done,r)
}
for i:=0;i<5;i++{
<-done
}
}

当我运行时使用

 go run -race thread.go

它给了

==================

WARNING: DATA RACE
Write by goroutine 5:
main.f()
usr/local/gocode/thread.go:12 +0x69

Previous write by goroutine 4:
main.f()
usr/local/gocode/thread.go:12 +0x69

Goroutine 5 (running) created at:
main.main()
usr/local/gocode/thread.go:25 +0xd3

Goroutine 4 (running) created at:
main.main()
usr/local/gocode/thread.go:25 +0xd3
==================

挂起

任何帮助都是有用的

最佳答案

这里有一个设计问题——你有一个 R 对象,它有一个共享实例,但每个 goroutine 都会创建一个新的本地计时器。在我看来,每个 goroutine 都需要一个本地计时器,而不是在所有 goroutine 之间共享该计时器,这没有意义。

如果您像这样重写代码:

type R struct {
//other fields
Foo string
Bar interface{}
}

func f(done chan bool, r *R) {
timer := time.NewTimer(time.Millisecond * time.Duration(1000+rand.Intn(2)))
//some code simultaneously accessing other fields of shared object r, cannot put a lock here
<-timer.C

done <- true
}

定时器成为 goroutine 的本地定时器,它应该是本地的,并且您没有竞争条件,至少对于定时器访问而言。

请注意,对共享对象的其他字段的访问必须受到互斥锁的保护,否则您将遇到同样的问题。

关于multithreading - 等待共享计时器的多个 go 例程导致竞争,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29766680/

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