简体   繁体   English

多个执行例程等待共享计时器导致比赛

[英]Multiple go routines waiting for a shared Timer causing race

I have a requirement to update timer of a shared object in multiple go routines. 我需要在多个go例程中更新共享对象的计时器。 But it end up with race condition. 但这最终导致了比赛条件。 I cannot use lock for waiting on the channel because all the other routines will have to wait. 我无法在通道上使用锁来等待,因为所有其他例程都必须等待。

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
    }
}

when I run using 当我使用

 go run -race thread.go

it gives 它给

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

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
==================

and hangs 并挂

any help would be useful 任何帮助都会有用

There is a design issue here - you have one R object, and it has a shared instance, but every goroutine creates a new timer that is local. 这里有一个设计问题-您有一个R对象,并且它有一个共享实例,但是每个goroutine都会创建一个本地的新计时器。 Seems to me like you need a local timer per goroutine, and not share that timer between all of them, it just doesn't make sense. 在我看来,您需要为每个goroutine提供一个本地计时器,而不是在所有程序之间共享该计时器,这没有任何意义。

If you rewrite your code like so: 如果您这样重写代码:

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
}

the timer becomes local to the goroutine as it should be, and you have no race condition, at least for the timer access. 计时器应变为goroutine的本地计时器,并且您没有争用条件,至少对于计时器访问而言。

Note that still, ever access to the shared object's other fields must be protected by a mutex or you'll get the same issue. 请注意,仍然必须使用互斥锁来保护对共享库其他字段的访问,否则会遇到同样的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM