Perhaps better illustrated:

package main

import (
        "fmt"
        "time"
)

type info struct {
        count int
        id    int
}

var stop int32

func runner(id int, c chan info) {
        info := info{id: id}
        for stop == 0 {
                info.count++
                time.Sleep(1 * time.Microsecond)
        }
        c <- info
}

func main() {
        c := make(chan info)
        for i := 0; i < 10; i++ {
                go runner(i, c)
        }

        time.Sleep(10 * time.Millisecond)
        stop = 1

        for i := 0; i < 10; i++ {
                fmt.Printf("Returned %+v\n", <-c)
        }
}

This program is guaranteed to halt, regardless of any GOMAXPROCS
setting. If you use the race detector on this program, it will
complain. You can "fix" "the race" by changing the loop condition to
"atomic.LoadInt32(&stop) == 0" and use atomic.StoreInt32(&stop, 1) as
your signal. Is the program still racy? Yep. Is either version of this
program buggy? That just depends. It's not too hard to think of cases
where this behavior might be desirable; even lossy counters are a
thing.

--dho

2018-03-18 0:43 GMT-07:00 Devon H. O'Dell <devon.od...@gmail.com>:
> 2018-03-16 2:16 GMT-07:00 Jérôme Champion <champ...@gmail.com>:
>> Any race is a bug. When there is a race, the compiler is free to do whatever
>> it wants.
>
> This is a false statement; whether or not a race constitutes a bug
> depends on the encapsulating protocol. Consider the following:
>
> package main
>
> import (
>         "fmt"
>         "sync"
>         "sync/atomic"
> )
>
> var wg sync.WaitGroup
>
> type Spinlock struct {
>         state uint32
> }
>
> func (s *Spinlock) Lock() {
>         for atomic.SwapUint32(&s.state, 1) == 1 {
>         }
> }
>
> func (s *Spinlock) Unlock() {
>         atomic.StoreUint32(&s.state, 0)
> }
>
> func locker(s *Spinlock, i int) {
>         defer wg.Done()
>         s.Lock()
>         fmt.Printf("Locker %d acquired lock\n", i)
>         s.Unlock()
> }
>
> func main() {
>         s := &Spinlock{}
>         for i := 0; i < 10; i++ {
>                 wg.Add(1)
>                 go locker(s, i)
>         }
>         wg.Wait()
> }
>
> This program does not have deterministic output because each goroutine
> races to acquire the lock, and which gets it first relies on
> scheduling, which is effectively stoachastic. (Playground caches
> output, so no use illustrating it there.) Despite this, the program
> compiles just fine and behaves correctly for any reasonable definition
> of correct.
>
> I recognize this is not the issue mentioned in OP, but hopefully it's
> clear that this is not just a semantics argument (race doesn't just
> mean "only things the race detector can find") and that the statement
> "any race is a bug" is false. This race only constitutes a bug when
> the requirements of this program require deterministic output.
>
> --dho
>
>> What do you want to do? Do you want to println before or after
>> cancelContext? In your example, println could even be executed during
>> cancelContext!
>> Your example is not enough, such program :
>> https://play.golang.org/p/KJsYwu-ivjb would fix your problem, but I don't
>> think that's what you asked for :)
>>
>>
>> Le vendredi 16 mars 2018 03:11:49 UTC+1, Anmol Sethi a écrit :
>>>
>>> https://play.golang.org/p/82Um1jSntBo
>>>
>>> Please run with the race detector to see the race.
>>>
>>> This race condition arises because private variables are read via
>>> reflection by the fmt package. Is there any elegant way to avoid such a
>>> race?
>>>
>>> --
>>> Best,
>>> Anmol
>>>
>> --
>> 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+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to