#why the outputs are different everytime

21 messages · Page 1 of 1 (latest)

ivory solar
#
package main

import (
    "fmt"
    "sync"
)

func main() {
    const gr = 500

    var wg sync.WaitGroup
    wg.Add(gr * 2)

    var n int = 0

    for i := 0; i < gr; i++ {
        go func() {
            n++
            wg.Done()
        }()

        go func() {
            n--
            wg.Done()
        }()
    }
    wg.Wait()

    fmt.Println(n)
}

Why the value of n is different evertime, my for loop is incrementing and decrementing the value of n for same no. time, then why the output is different on each compile

mighty carbon
#

don't you have a race cond with it?

worthy veldt
#

because n is not guarded with a mutex
thus race conditions can happen

ivory solar
#

I am just a beginner, not sure how the race condition is taking place here

worthy veldt
#

lets imagine something simpler
i tell bob to read the value of N and assign the result of N + 1 onto N
now i also tell alice to the same thing
now bob goes up to find N, reads it
then go and proceed to compute the result of N + 1
after some time after bob is done computing
bob assigns the result back to N

at the same time alice is doing the same thing...
both parties does not wait for eachother to be done with their computation
the slower party overwrites the faster party's computation

#

so the result is N+1 not N+2

#

a mutex enforce cooperativeness between 2 parties
bob takes the mutex, and computes the result
alice cannot do anything except waits for bob to be done with the mutex first

ivory solar
#

ok I understand

#

thanks

ivory solar
#

I heard channels are also a thinkg, should I use channel or mutex for this particular case

mighty carbon
#

i usually go with mutex, sometimes atomic but that's rare and kinda hard to use

ivory solar
#

atomic?

#

what is that

worthy veldt
#

you could use channels but i dont think it make sense here
for example you could have a dedicated go routine which reads from a channel
and sum channel's value with n
if another routine want to increment n
it needs to send 1 into the channel

#

this way only the routine has exclusive access to n

#

it's not so applicable for every case though

#

say what if you want to overwrite n with 10
you basically cannot do it in this system

#

you could read n and send a value which gets n to be sum as 10, but in meantime some other routine could request it to be incremented by 1, and thro off your caculation