Do I need to worry about this race condition?

240 views
Skip to first unread message

Art Mellor

unread,
Apr 19, 2015, 9:35:27 AM4/19/15
to golan...@googlegroups.com
I have a race condition that is clearly real. I don't think it will cause a problem, but I wanted to make sure I'm not missing something non-obvious, either in a side-effect or in a better way to do it.

Below is a stripped down toy version of what I'm working with, I also have it in the playground. The race condition output is below the code listing.

Basically, I'm swapping out a func in a var to turn debug output on/off. My thoughts are that the assignment is "atomic" and thus I'm not at risk for unexpected behavior. I realize I could embed it in a struct with appropriate methods and a lock, but I like having it behave as a straight func.

(obviously running it in the playground won't show the -race output)

It's a go routine printing debug output and a main routine turning the debug on and off.

Is there something bad possibly happening that I'm missing or a better way to do this. I also like having clean -race output.
Thanks!

package main
import (
    "fmt"
    "time"
)
func DebugOn(fmtstr string, args ...interface{}) {
    fmt.Printf(fmtstr, args...)
    return
}
func DebugOff(fmtstr string, args ...interface{}) {
    return
}
var Debug = DebugOn
func main() {
    go func() {
        for i := 1; i <= 100; i++ {
            Debug("%03d: Debug\n", i)
            time.Sleep(100 * time.Millisecond)
        }
    }()
    for i := 1; i <= 5; i++ {
        time.Sleep(1 * time.Second)
        Debug = DebugOff
        time.Sleep(1 * time.Second)
 Debug = DebugOn
    }
    return
}
/*
==================
WARNING: DATA RACE
Write by main goroutine:
  main.main()
      /emu/build/art/repo/Go/src/race/race.go:30 +0x6c
Previous read by goroutine 5:
  main.func-001()
      /emu/build/art/repo/Go/src/race/race.go:23 +0xf1
Goroutine 5 (running) created at:
  main.main()
      /emu/build/art/repo/Go/src/race/race.go:26 +0x37
==================
*/

Brad Fitzpatrick

unread,
Apr 19, 2015, 10:18:50 AM4/19/15
to Art Mellor, golang-nuts
Once you have any race, all bets are off. There is no such thing as a benign race.


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Tamás Gulácsi

unread,
Apr 19, 2015, 10:19:20 AM4/19/15
to golan...@googlegroups.com
There's no such thing as benign data race: https://software.intel.com/en-us/blogs/2013/01/06/benign-data-races-what-could-possibly-go-wrong

So guard it with a muted - you can hide the muted into a function, if you wish.

Art Mellor

unread,
Apr 19, 2015, 11:17:53 AM4/19/15
to golan...@googlegroups.com
Thanks for the pointer to that article - just what I needed.

Also, hadn't thought of wrapping the func in a func to hide the mutex. Great idea.


On Sunday, April 19, 2015 at 9:19:20 AM UTC-5, Tamás Gulácsi wrote:

atd...@gmail.com

unread,
Apr 19, 2015, 11:32:07 AM4/19/15
to golan...@googlegroups.com
Perhaps something like that can help:

Art Mellor

unread,
Apr 19, 2015, 11:50:06 AM4/19/15
to golan...@googlegroups.com
I literally just completed writing almost the exact code, although yours is slightly more elegant - so I'll steal that.

Thanks - exactly what I was looking for!

John Waycott

unread,
Apr 19, 2015, 12:01:29 PM4/19/15
to golan...@googlegroups.com
Here's another take, more like your original idea of swapping functions:

It would be useful if you wanted to swap out different types of debug functions.

atd...@gmail.com

unread,
Apr 20, 2015, 8:33:08 AM4/20/15
to golan...@googlegroups.com
A bit cleaner of an example, (added the possibility to provide an alternate logging function as John mentioned it could be useful)
http://play.golang.org/p/FaDIzeBc9t

Reply all
Reply to author
Forward
0 new messages